home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 …ember: Reference Library / Dev.CD Dec 94.toast / Technical Documentation / Mac Tech Notes (DocViewer) / HW • Hardware / HW01 ADB (Space Aliens) / HW01 ADB (Space Aliens)
Encoding:
Text File  |  1994-10-19  |  156.0 KB  |  270 lines  |  [ONLN/HLX2]

  1. ADB–The Untold Story : Space Aliens Ate My Mouse
  2. Hardware    
  3. Written by:    Tim Dierks, Jim Mensch    January 1994
  4. Originally by:    Cameron Birse, Rich Kubota
  5. This Technical Note explains a number of esoteric and unknown issues concerning the Apple Desktop Bus (ADB).  It incorporates material from the original version of this note, along with a large amount of new information, and is intended to detail information concerning all levels of the ADB, from the hardware to the application usage level.  This note is supplementary to the information in The Guide To Macintosh Family Hardware and in the Apple Desktop Bus Specification. The information in the specification is the most accurate source of data, and unless it is specifically refuted, it should be treated as the authoritative source.
  6. Changes since October 1991:  This note has been rewritten; new information appears throughout the document.  In particular, the Cursor Device Manager is discussed in this note for the first time. The information regarding bugs fixed in System 6.0.4 was omitted.
  7. Topics
  8. •    A discussion of ADB hardware issues
  9. •    Information on the ADB protocol, including a detailed description of the relocation and autopolling mechanisms.
  10. •    The recommended method of ADB driver installation
  11. •    Documentation for the Cursor Device Manager
  12. •    Description of the data formats used by Apple mice and keyboards
  13. •    How to get an ADB license
  14. The ADB Hardware
  15. The ADB is a simple serial bus with collision detection.  A common implementation platform for the protocol is a simple microcontroller; a 2 MHz Motorola 68HC11 has been used with success, although any number of microcontrollers would do a more than adequate job.  The 2 MHz clock seemed to be close to minimal for this application.  The bus has a relatively low bandwidth; given the packet structure, the theoretical maximum bandwidth is on the order of 100 - 200 bytes/second.  In practice, the bus is not suitable for data transfer applications; it serves well as a general purpose input device bus, but high data rates will not work well.
  16. In general, the timing for the ADB is fairly tolerant of small variances; however, many recent Macintoshes are more demanding than their predecessors. For this reason, devices should be tested on a wide range of machines; the best test for compliance is testing.  Specifically, the Tlt (stop to start time) parameter has become much less tolerant in recent Macintoshes; fairly close adherence to its 200 µs timing is important.  In particular, devices which respond more rapidly than the 140 µs minimum delay will often fail to initialize properly.
  17. It is important that your device be fairly tolerant of problems on the bus; if a command packet begins but never seems to complete, your device should time out rather than hang; the design of the bus and its connectors means that there can be occasional glitches in the connection with the host, and you should try to be as tolerant of these as possible. 
  18. Because the ADB bus is open collector, collisions can be detected when a device is attempting to drive the bus high and another device pulls it low.  This means that whenever the device is driving the bus high, it should be watching to make sure the bus is actually high; if the bus goes low, some other device is sending at the same time. When a device detects a collision, it should immediately stop transmitting; this means that if two devices are colliding, one of them will detect the collision, while one will not.  This is because a device can only detect the collision if it is driving the bus high and another device drives it low.  The device driving it low has no way to tell that there was a collision, as the bus follows it.  Since the detecting device immediately stops transmitting, the other device will not detect the collision.  Thus, if there are a number of devices transmitting on the bus, only one of them will complete its transmission without detecting the collision, unless the unlikely occurrence of more than one device transmitting exactly the same data with the same timing occurs, and neither detects the collision.
  19. The ADB is not particularly tolerant of devices being connected and disconnected while the bus is live. There isn't any software architecture to detect the presence of new devices or the absence of old ones; furthermore, on some CPUs, the motherboard is not well protected from voltage transients on the ADB connector; plugging in a device while the Macintosh is on could cause damage to the ADB transceiver or other portions of the Macintosh's circuitry.
  20. On some portable Macintoshes, the voltage characteristics are not exactly what is specified in the ADB spec.  Clearly, power is very valuable on all portable computers, so if your device is targeted towards portable use, you should be extremely careful to keep your power consumption as low as possible; while the ADB can supply the full voltage specified in the spec., drawing this much power will lead to much more rapid battery draining. On the PowerBook 140 and 170, there was a specific problem which caused the low-level input voltage to go above the specified maximum of 0.8 volts; it commonly came close to 1.5 volts. This has caused problems for some third-party devices; it has been corrected on all more recent machines. There is a recommended service procedure for repairing this problem available from Apple Service representatives, should this be a problem for a user.
  21. Soft Power
  22. On Macintoshes with software power control, the machine can be turned on by an ADB device.  This is accomplished by momentarily connecting pin 2 on the ADB connector (reserved) to pin 4 (ground).  Pin 2 should be kept grounded until pin 3 (+5 volts) comes up to power, letting you know that the machine has actually come on.  Some Macintoshes do not have soft power capabilities; on these machines, grounding pin 2 will have no effect.
  23. The ADB Protocol
  24. Registers
  25. Each ADB device has four logical registers; the host can ask the device to talk or listen on each one of these registers; a talk command asks the device to output the stored value from that register; a listen commands asks the device to accept a new value for that register.  A register can contain between 2 and 8 bytes.  Some of the registers have predefined functions: register 0 is used as the primary data transfer register for most devices; it is this register which is polled by the input mechanism (as described below).  Register 1 has no specified use; it is available for any use the device might require.  Register 2 has no specified use for most devices; the ADB specification does define an "extended address device" protocol for register 2 on devices at address 1, but this is unused by most developers.  Register 3 is used to identify devices and to separate devices which occupy the same address, as discussed in "Address Resolution" below.
  26. Default addresses and handler IDs
  27. Each ADB device identifies its software interface with two constants; the default address and the handler ID.  This pair uniquely identifies a device's software interface; the default address usually specifies a device's general type (such as relative pointing device or keyboard) while the handler ID specified the particular data protocol this device uses for communication.  The default address categories are as follows:
  28. Default Address    
  29. Device Type    
  30. 1    Security & Dongles    
  31. 2    Keyboards    
  32. 3    Relative pointing devices (mice)    
  33. 4    Absolute pointing devices (tablets)    
  34. 5    Low speed data transfer devices    
  35. 6    Reserved (PowerBook Duo charger)    
  36. 7    Appliances (Miscellaneous catch-all)    
  37.  
  38. Table 1–Default address categories
  39. The default address is only a guide; there's no real reason a mouse can't be at address 7, but default addresses are assigned on a category basis to try to avoid the case where a user has more than one device at a particular address; by putting all the relative devices at address 3, collisions will be avoided at address 3 for all users who have only one relative pointing device.  While the bus is robust with respect to seperating devices which are at the same address, the ADBS driver loading mechanism, which is described blow, made it useful to try to avoid having several dissimilar devices at the same address.
  40. Default addresses and handler IDs are assigned by Apple Software Licensing when an ADB license contract is completed.  Default address 0 is used by the ADB host; addresses 8 through 15 are used as locations to dynamically locate devices at.
  41. Some devices support more than one data protocol.  An example is the extended keyboard, which can be asked to send separate key codes for the left & right shift keys.  This change is accomplished by changing its handler ID to 3; the new handler ID reflects the new data protocol.  If your device receives a request to change handler IDs (via a listen register 3 command), it should only obey the request if it knows how to speak the protocol specified by the new handler ID.  For example, the extended keyboard, when receiving a request to change handler IDs, should accept the change if it is going to ID 3 or some other ID it knows about, and should thereafter report that ID as its own in response to talk register 3 commands; if it receives a request to change to handler ID $52, it should ignore it, as it does not know what handler ID $52 implies, and continue to report its original handler ID in response to talk register 3 commands.
  42. A special case is devices which emulate Apple device protocols.  For example, you may be constructing a 17-button mouse for use by specially trained squid; it has a special software protocol to allow it to convey the state of all 17 mouse buttons.  However, you may wish to emulate the Apple mouse protocol so your device can be used as a one button mouse on machines which don't have your driver software installed.  Due to the software design of the ADB manager, if your device is at default address 3, it will have the default mouse driver installed as its driver at startup regardless of its handler ID; when your software loads, you can install a new driver for your device and tell it to begin talking the 17 button protocol.  You have two options: you can have your device power up with the default Apple mouse handler ID ($01) or with your own handler ID as assigned by Apple Software Licensing.  If you power up with the $01 handler ID, your software will have to locate your device by trying to change the handler ID of each device which started out at address 3 to you custom ID, then reading the handler ID of that device back; if the change stuck, then you know you're talking to your device, and can install your custom driver.  In addition, the command to change handler IDs told the device to begin using your custom protocol.  Alternatively, you could have your device power up with your custom handler ID; this would make identifying your device somewhat easier, as your device could be identified by its special handler ID; you would have to use some special command to tell the device that you have installed the new driver and that it can begin speaking the custom protocol.  For example, you could use a talk register 1 to tell the device that you're ready for the 17 button data protocol.  Both approaches work well, but the first one is recommended; it ensures that the current protocol can always be determined by looking at the current handler ID; however, it relies on all devices at that default address handling commands asking them to change to a different handler ID properly, as a device which incorrectly changes its handler ID to your assigned ID would fool you into thinking it was your device.  This doesn't seem to be a large problem, but there could be some obscure devices with this bug.
  43. Address Resolution
  44. Address resolution is the process the ADB manager uses to separate devices which share the same default address, so they power up shadowing each other at a particular address.  It relies on devices using collision detection to determine when there is more than one device at a particular address.
  45. An ADB device's register 3 is 2 bytes long and includes 4 bits in which the address is stored.  When the device receives a listen register 3 command, it should take its address from this 4 bit field.  When it receives a talk register 3 command, it would be redundant to put the device's address in that field; the device's address is already uniquely determined by the fact that the device is responding to the talk register 3 command, which was sent to a specific address.  Instead, a random 4-bit value should be returned in this field; this makes it easier to detect collisions between two devices responding to a talk register 3.
  46. When a device receives a talk register 3 command, it should send back all of register 3, including the random field, and it should pay careful attention to collision detection. Should a device detect a collision when responding to a talk register 3 request, there is a special provision in the ADB protocol which says that the device should ignore the next listen register 3 which asks it to change address. The next time the device receives a listen register 3 command, it should check to see if the handler ID field is set to $FE.  This is a reserved handler ID used to distinguish this type of listen request; if the handler ID field is $FE, the device should only change address if it has safely transmitted a complete packet since its last collision.  Of course, the device should not adopt the handler ID of $FE.
  47. Here is a summary of a typical sequence where the host is attempting to separate two devices.  There are two devices of the same type, which I will call Fred and Wilma, at address 3.
  48. 1) The host will send a talk register 3 command to address 3.
  49. 2) Both Fred and Wilma will receive the command and begin to respond.
  50. 3) Even though they are sending the same data, and they begin sending at the same time, they select different random numbers to insert into the "device address" field of register 3, bits 7-10.
  51. 4) Wilma detects a collision while trying to send bit 7 and immediately stops sending.
  52. 5) Fred does not detect a collision and completes his transmission of register 3.
  53. 6) The host, seeing that a device has responded to its talk register 3, sends a listen register 3 to address 3, asking the device there to move to address $F.  The handler ID field is $FE, indicating that a device should not move if it has detected a collision.
  54. 7) Both Fred and Wilma receive the request.
  55. 8) Fred moves to address $F; however, Wilma does not, as she has been locked out of moving because she detected a collision while responding to her last talk register 3 command.
  56. 9) The host sends a talk register 3 to address $F to ensure that a device moved there.  Fred responds, assuring the host he has moved.
  57. 10) The host repeats the separation procedure, sending a talk register 3 to address 3, followed by a listen register 3 to address 3 asking the device there to move to address $E.
  58. 11) This time, Wilma does not detect a collision, as she is the only device remaining at address 3, so she moves to address $E.
  59. 12) The host sends yet another talk register 3 to address 3, but does not receive a response, as there are no more devices remaining at address 3.
  60. 13) The host relocates Wilma from address $E back to address 3 with a listen register 3 command sent to address $E.
  61.     14) The host moves on and repeats the process for address 4.
  62. Each and every ADB controller isn't guaranteed to follow this procedure precisely, but it gives a feeling for the principle behind the address resolution process.  You may see some implementations moving devices many more times than is necessary; this is done because some devices have been manufactured to tolerances close enough that not only do they send their bits at exactly the same time and so cannot detect collisions with each other, but they select the same random numbers to transmit.  We recommend that you include some low tolerance device (such as a capacitor on your reset line) to ensure that various devices will respond differently and be able to detect their collisions with each other.
  63. Autopolling
  64. Autopolling is the primary method via which the host fetches data from your device.  The basic mechanism is that the host repeatedly issues talk register 0 commands to your device; if your device responds with data, it is passed to your device's driver, which should act on it as new data.
  65. This implies that register 0 should be the primary data transfer register for most devices; registers 1 and 2 are usually only used for supplementary data to configure the device.  Most device drivers have no need to issue commands to their device, as all necessary data has been transferred within register 0.
  66. When a device wishes to transmit data, it should wait until a command is issued to it or some other device.  If, when this transmission is completing, it still wishes to transfer data (if the command was sent to our device, it might have fetched the data already,) it should assert SRQ after the data portion of the command by holding the bus low for 300 µs after the stop bit.  This will alert the host that some device wishes to transmit data.  It will then begin polling those addresses which it knows hold devices.  If a device does not have any data, the host will move on to the next address, asking each device in turn, until SRQ is no longer asserted, indicating that all pending data has been fetched.
  67. When an SRQ is not asserted, the host will continually poll the last device to send it data, sending it talk register 0 commands periodically.  This is done under the assumption that this is likely to be the next place the user interacts; if the user types a character, she is very likely to type another soon.  On current hosts, this can happen up to 150 times a second, although it can happen much less frequently in some cases. If the device responds with any data, the host will call the device's driver with the data.
  68. Your device should only respond with data when sent a talk register 0 command if it has new data. If the status of the device has not changed since the last talk register 0, then it should not respond at all, allowing the bus to time out. This is useful for two reasons: first, it tends to reduce the demands on the host, as your driver need not be called when your device has nothing useful to say. Second, in some ADB implementations, the host can get "hung up" on your device if you always respond. For example, say that you have a device at address 4 which will always respond, regardless of whether it has new data, there is another device at address 7, and the system is currently autopolling address 2. If the device at address 7 asserts SRQ, the system will begin looking through the addresses looking for the device which has data to send.  When it reaches your device at address 4, your device will respond, although it has nothing new to say. On some implementations, this will cause the host to repeatedly ask your device for more data, and your device will continue responding. Meanwhile, device 7 is withering away at the end of the bus and will never get serviced. What your device should do is not respond to the talk register 0, as it has no new data; this will allow all host implementations to pass you by and reach the device at address 7 which needs the host's attention.
  69. A useful summary of a reasonable algorithm is:
  70. •    Wait for a command to begin
  71. •    If the command is directed to my address, handle it.  If it is a talk register 0 command, only respond if there is new data waiting to be sent.
  72. •    At the end of the command, if there is data waiting to be sent, assert SRQ, regardless of who the original command was directed towards.
  73. This simple behavior will produce the appropriate responses and SRQ generation for proper bus functioning.  It shouldn't be necessary for your device to explicitly have any knowledge of whether it is the "active" device or not; a robust basic behavior will eliminate any need for such information.
  74. As an optimization, all recent versions of the ADB manager will not automatically poll a device which does not have a driver service routine installed.  In this case, they will switch to autopolling some other device, even if that device has not been recently communicated with.  However, the host may poll a device, even if it does not have a service request, in order to try to clear an SRQ on the bus.
  75. Bus Initialization
  76. Bus initialization doesn't work exactly as it might seem from looking at some documentation.  A SendReset command is never sent to individual devices; rather, when a bus reset is requested, the ADB manager sends a SendReset command which is broadcast to all devices, causing them to reset themselves and go to their default addresses and handler IDs.  The relocation and driver loading procedure will follow immediately after the reset command is sent.
  77. ADB Drivers
  78. Driver Installation
  79. In the past, the recommended way to install an ADB driver was to install a resource of type 'ADBS' with the same resource ID as your device's default address in the system file which held code to install the driver for the ADB driver, along with the driver itself.  When the system was booted or when the bus was reinitialized, the system would get the 'ADBS'resource and execute it, which would let your code set the driver for that device up.  Unfortunately, this system is not well designed for the wide variety of devices available; the most prominent flaw is that the 'ADBS'resources are indexed by default address only; thus, there is no way to use the 'ADBS'mechanism to load drivers for two different devices at address 7, as there can be only one resource with ID 7.  A further flaw is that it requires installation into the system file, which is not currently recommended for a number of reasons.  In any case, it has always required a special installation and deinstallation program and has been more than a little confusing for users.
  80. Currently, the recommended method is to supply the user with a system extension which will load your driver; this can either be a simple extension, or it can be contained within a control panel, should your device require some user interface for configuration.  Your code, when loaded, should look for your device and install your driver for it. If your device is at a default address which is not shared with standard Apple devices, you don't have to concerned with what driver is installed for you by default; your device can just power up at its standard address with its handler ID.  Your extension can then locate your device's current address by indexing through all the known devices with the ADB manager call GetADBInfo(); when you find a device whose initial address and handler ID match your device's, you can call SetADBInfo() to install your driver's completion routine to handle autopolled data from your device.
  81. Because your ADB driver is in a system extension which will not load until well into the system startup process, if your device is a standard one (a pointing device or keyboard) you might need to provide standard system functionality before your driver loads in order to allow the user to interact with the system during the startup process.  This also allows the user to use your device to control their machine even if they don't have the software installed, such as when they are booting off of a floppy.  In this case, your device will need to be able to emulate the Apple protocol for mouse or keyboard devices until your software driver loads, as discussed above in "Default Addresses and Handler IDs".  Until your driver is installed, your device will be serviced by the default driver for this address; this means that if your device is at address 2 or 3, even if it cannot emulate an Apple device, it must supply harmless data in register 0 until your driver loads and is installed, as the Apple ADB driver for that address may inadvertantly receive the contents of your register 0 and attempt to use it as input data.  If the data in your field caused effects such as the mouse button or shift key sticking down, this could cause problems for the user.
  82. If you use the recommended procedure for handler IDs in this case, powering up with the appropriate Apple handler ID and switching to your custom ID when your driver loads, you will need to use ADB commands to find your device at startup.  You should index through the connected ADB devices with GetADBInfo() and if you find a device which has an original address and handler ID which indicates that it might be your device, attempt to switch it to your handler ID by using ADBOp() to send it a listen register 3 to change its handler ID.  (You will first need to read its register 3 with a talk register 3 command so you can correctly copy the various flag bits in the register you send to the device.)  You should then issue a talk register 3 command to the device and examine the response to see if the new handler ID was accepted and reported back by the device; if so, you can be certain that this device is your device and you can then call SetADBInfo() to install your driver as the handler for that device.
  83. In the original method using 'ADBS' resources, the system could automatically reload your driver any time the bus was reinitialized.  If your driver is loaded via a system extension there isn't any way for the system to find your device and driver and reconnect them after the bus is reinitialized and devices are relocated.  Thus, you've got to manually reconnect your driver to your device each time the bus is reinitialized.  Fortunately, there is a system provision for you to be notified each time the bus is reinitialized; there is a low memory global called jADBProc (at address $6B8) which is a pointer to a procedure to be called just before and just after the bus is initialized.  When the procedure is called before the bus is initialized, register D0 is set to 0; after, it is set to 1.  When your extension loads and installs your driver, you should remember the value in the jADBProc global and then install a pointer to a procedure of your own in that location; when this procedure is called, it should do its thing, then call through to the next procedure in the chain, whose address was in jADBProc before you replaced it (if jADBProc was equal to 0 before you installed, just return from your procedure).  Don't forget to preserve register D0 so subsequent procedures can tell if they are being called before or after the reinitialization.  The actions you take in the post-initialization case should basically duplicate your original installation procedure, including looking through all the devices for devices of your type and calling SetADBInfo() to install your driver for your devices.
  84. For history buffs, this is the second time we've changed our recommended procedure for loading ADB drivers.  Initially, it was recommended that ADB drivers be loaded with INITs; however, at the time, jADBProc did not exist, so when the Macintosh Portable came out, INIT-handled devices had the fatal flaw of not reloading their drivers when the Macintosh was put to sleep and reawakened, since this procedure involved resetting the bus.  This cause us to begin recommending the use of the 'ADBS'resource, since in this way the driver could be reloaded from the System file.  However, the 'ADBS'approach has so many major flaws that we have stopped recommending it now that the jADBProc global has been introduced.  As far as I can tell, jADBProc has been available at least since System 6.0.4.
  85. For true history buffs, or possibly for specialized applications, here is the description of the 'ADBS'resource functionality: the 'ADBS'resource is loaded into the system heap by the system and detached with DetachResource().  The resource is then called by JSRing to the first byte of the resource. At this time, the registers are set up as follows: A0 holds the address of the 'ADBS'resource data (although it is no longer in a resource handle, thanks to the DetachResource() call); if a handle to the resource is needed, RecoverHandle() can be called to retrieve it.  The low byte of register D0 holds the ADB device's current address (due to relocation, this might not be the same as the default address) and the low byte of register D1 holds the handler ID of the device in question.
  86. The Cursor Device Manager
  87. In order to be able to manage an expanding set of relative movement devices, Apple has created the Cursor Device Manager, which is a software architecture which provides a standard interface to devices of widely varying resolutions and capabilities.  This also allows better management of multiple relative devices on a single bus; in the old architecture, all connected devices shared a single button state and acceleration curve, which became a problem for Apple and for third-party device manufacturers.  The Cursor Device Manager provides a number of calls for finding, configuring, and manipulating relative devices connected to the bus.  It also supports the new extended mouse protocol, which is described below in the "Apple Devices" section.
  88. Cursor Device Manager types
  89. The Cursor Device Manager treats each relative or absolute device as a "Cursor Device".  Each one is specified by a CrsrDevRec which is defined as follows:
  90. CrsrDevPtr = ^CrsrDevRec;
  91. CrsrDevRec = RECORD
  92.     nextCrsrDev    :CrsrDevRec^    ; ptr to next record in linked list
  93.     whichCursor    :CrsrDataRec^    ; ptr to data for target cursor
  94.     refCon    :LongInt    ; Application defined
  95.     unused    :LongInt    ; reserved for future
  96.     devID    :OSType    ; device identifier(from ADB reg 1)
  97.     resolution    :Fixed    ; units/inch (orig. from ADB reg 1)
  98.     devClass    :Char    ; device class     (from ADB reg 1)
  99.     cntButtons    :Char    ; # of buttons     (from ADB reg 1)
  100.     spare1    :Char    ; reserved
  101.     buttons    :Char    ; state of all buttons
  102.     buttonOp    :Array[0..8] of Char    ; action performed per button
  103.     buttonTicks    :Array[0..8] of LongInt    ; ticks when button last went up        buttonData    :Array[0..8] of LongInt    ; data for the button operation
  104.     doubleClickTime    :LongInt    ; device’s double click time
  105.     acceleration    :Fixed    ; current acceleration
  106.     accelPoints    :Ptr    ; Private: Ptr to array of  (dev_delta,
  107.             ;     slope, intercept)
  108.     deltaX    :Fixed    ; Private: accumulated deltas
  109.     deltaY    :Fixed    ; Private:         "
  110.     errorX    :Fixed    ; Private: accumulated errors
  111.     errorY    :Fixed    ; Private:         "
  112.     denom    :Fixed    ; Private: fraction of the errors to
  113.             ;     use next time
  114.     spread    :Fixed    ; Private: Number of samples to spread
  115.             ;     errors over
  116.     newData    :Char    ; Private: set when deltas are new
  117.     spare2    :Char    ; reserved
  118. END;
  119. The cursor controlled by this cursor device is described with a CrsrDataRec:
  120. CrsrDataPtr = ^CrsrDataRec;
  121. CrsrDataRec    = RECORD
  122.     nextCrsrData    :CrsrDataRec^    ; next in global list    
  123.     displayInfo    :Ptr    ; reserved for future use
  124.     whereX    :Fixed    ; horizontal position
  125.     whereY    :Fixed    ; vertical position
  126.     where    :Point    ; the pixel position
  127.     isAbs    :Boolean    ; has been stuffed with absolute coords
  128.     buttonCount    :Char    ; number of buttons currently pressed
  129.     screenRes    :Integer    ; Pixels per inch on the current display
  130. END;
  131. Most of the fields are fairly self-explanatory.  The fields labeled as private at the end of the CrsrDevRec are used to manage cursor acceleration and shouldn't be modified by your software.  Some of the usage of the other fields will be explained below in the description of the cursor device manager routines.
  132. Cursor Device Manager Routines
  133. CrsrDevNextDevice:
  134. Function CrsrDevNextDevice(VAR curDevice: CrsrDevPtr):OSErr;
  135. CrsrDevNextDevice() can be used to index through the various devices the Cursor Device Manager is aware of.  You pass it a CrsrDevPtr; initialize this variable to nil to advance to the first device in the list, then call CrsrDevNextDevice() repeatedly, each time passing the CrsrDevPtr as it was last modified; when you have reached the end of the device list, the pointer returned in the curDevice parameter will be 0.
  136. CrsrDevNewDevice:
  137. Function CrsrDevNewDevice(VAR ourDevice: CrsrDevPtr):OSErr;
  138. Call CrsrDevNewDevice() to create a new cursor device and link it into the device chain. The new device record will be initialized with values representing a standard one-button mouse; you should call CrsrDevSetAcceleration() for the device after creating it. A pointer to the created device is returned in the ourDevice variable.
  139. New cursor devices are created for all ADB address 3 devices. This routine should only be needed by devices which are connected though some other method, such as the serial port.
  140. CrsrDevDisposeDevice:
  141. Function CrsrDevDisposeDevice(ourDevice: CrsrDevRec):OSErr;
  142. This routine disposes of a cursor device and unlinks it from the device chain.  This isn't needed by most developers, but could be useful for non-ADB devices which might be connected and disconnected.
  143. CrsrDevMove:
  144. Function CrsrDevMove(ourDevice: CrsrDevRec;
  145.                      deltaX,deltaY: LongInt):OSErr;
  146. CrsrDevMove() accumulates the deltaX and deltaY values into the recorded movement of the device; the next time the cursor position is calculated, these deltas will be fed through the acceleration algorithm and used to move the cursor.  This routine should be called by a relative device driver with the data it receives from its device, even if the deltas are both zero; this lets the acceleration algorithm properly calculate the appropriate motion.  This routine is automatically called by the default driver for address 3 devices; you would only need to call it if you were using a custom driver.
  147. CrsrDevMoveTo:
  148. Function CrsrDevMoveTo(ourDevice: CrsrDevRec;
  149.                        absX,absY: LongInt):OSErr;
  150. CrsrDevMoveTo() sets the absolute position of the cursor to (absX, absY).  The next time the cursor position is calculated, it will be moved to this absolute location.  This would normally be used by a driver for an absolute pointing device to position the cursor.
  151. CrsrDevFlush:
  152. Function CrsrDevFlush(ourDevice: CrsrDevRec):OSErr;
  153. CrsrDevFlush() causes the acceleration and motion algorithms to flush out all their error collection and motion deltas into the cursor position; it indicates that your device is done moving temporarily.  This may be useful for devices which can tell when they become idle (such as a stylus pointing device); if they call this routine when they become idle, it ensures that all unused motion data will be worked into the cursor position at the next time it is calculated.
  154. CrsrDevButtons:
  155. Function CrsrDevButtons(ourDevice: CrsrDevRec;
  156.                         buttons: Char):OSErr;
  157. CrsrDevButtons() handles posting mouseUp and mouseDown events and also deals with debouncing mouse clicks.  Pass the current button status in the buttons parameter, going from bit 0 is button 0 to bit 7 representing button 7.  For each button, a one bit represents down, a zero bit represents up.  This routine debounces mouse clicks to keep them from looking like double clicks; if the button goes down less than 2 ticks after coming up, then the mouseDown will be ignored. Button up events are never ignored to avoid problems such as continuous scrolling which are confusing and difficult for the user to deal with.  A device driver should call this routine any time it gets a data packet; this routine deals with keeping track of whether the button state has changed.  This routine automatically calls routines installed with CrsrDevButtonOp().
  158. CrsrDevButtonDown:
  159. Function CrsrDevButtonDown(ourDevice: CrsrDevRec):OSErr;
  160. CrsrDevButtonDown() posts a mouseDown event if this is the first button to go down for this device.  It is called by the standard button operation routines; you should need to call it only if you use a custom button operation routine.
  161. CrsrDevButtonUp:
  162. Function CrsrDevButtonUp(ourDevice: CrsrDevRec):OSErr;
  163. CrsrDevButtonUp() posts a mouseUp event if this is the last button to come up for this device.  It is called by the standard button operation routines; you should need to call it only if you use a custom button operation routine.
  164. CrsrDevButtonOp:
  165. Function CrsrDevButtonOp(ourDevice: CrsrDevRec; btnNo: Integer;
  166.                          opCode: Integer; data: LongInt):OSErr;
  167. CrsrDevButtonOp() sets a new operation to be associated with a particular button.  btnNo may range from 0 to 7, and opCode specifies what operation to use.  The data field specifies a parameter for the operation you are setting for the kButtonCustom operation.  The opCode parameter may have one of the following values:
  168. kButtonNoOp    No action    
  169. kButtonSingleClick    Normal mouse button    
  170. kButtonDoubleClick    Click, release, and click again when pressed    
  171. kButtonClickLock    Click on press, release on next press    
  172. kButtonCharStroke    Unimplemented, reserved    
  173. kButtonAppleScript    Unimplemented, reserved    
  174. kButtonCustom    Call a custom procedure; data holds its address    
  175.  
  176. Using the btnCustom operation will cause a procedure whose address is passed in data to be called whenever this button changes state.  The procedure takes the following parameters: the address of the CrsrDevRec record for its device is passed in register A2; the button being pressed or released is in register D3.  The new state of the button will already have been filled into the buttons field in the CrsrDevRec, so you may use that flag to determine if the button is being clicked or released.  Your routine may destroy registers D0, D2, A0 and A1; it must preserve all other registers.
  177. The kButtonCharStroke and kButtonAppleScript operations are currently unimplemented and will simply cause the button press to be ignored.
  178. CrsrDevSetButtons:
  179. Function CrsrDevSetButtons(ourDevice: CrsrDevRec;
  180.                            numButtons: Integer):OSErr;
  181. CrsrDevSetButtons() allows you to set the number of buttons on the device specified by ourDevice to numButtons.
  182. CrsrDevSetAcceleration:
  183. Function CrsrDevSetAcceleration(ourDevice: CrsrDevRec,
  184.                                acceleration: Fixed):OSErr;
  185. CrsrDevSetAcceleration() lets you set the acceleration for the device specified by ourDevice to the value specified by acceleration, where 0 ≤ acceleration ≤ 1.  The Cursor Device Manager will build an acceleration table for the device based on its device ID or device class and the desired acceleration value.  For details on acceleration resources, see "Acceleration Tables" below.  The acceleration table set by CrsrDevSetAcceleration() is found by interpolating the tables stored in the appropriate acceleration resource.  All 'accl' resources in the resource chain or in the ROM are searched looking for the one applying to the specified device, so a control panel which called CrsrDevSetAcceleration() could implicitly use 'accl' resources stored within the control panel's resource fork.
  186. CrsrDevDoubleTime:
  187. Function CrsrDevDoubleTime(ourDevice: CrsrDevRec;
  188.                            duration: LongInt):OSErr;
  189. CrsrDevDoubleTime() lets you set the double-click time associated with a particular device.  The duration parameter specifies the time, in ticks, to use as the double-click time for this device.  An application could be written to check the double-click time for the particular device in checking for a double-click.
  190. CrsrDevUnitsPerInch:
  191. Function CrsrDevUnitsPerInch(ourDevice: CrsrDevRec;
  192.                              resolution: Fixed):OSErr;
  193. CrsrDevUnitsPerInch() lets you set the resolution of a particular device to its physical resolution, in units per inch.  For devices adhering to the Apple extended mouse protocol, this call shouldn't  be needed, as the resolution can be read from the device's register 1; however, this call might be made by a driver for a device which doesn't use the ADB.
  194. Acceleration Tables
  195. Acceleration tables are stored in resources of type 'accl', which have the following Rez description:
  196. type 'accl' {
  197.     literal longInt    /* Device identifier or device class     */
  198.         classAbsolute,    /* A flat-response device     */
  199.         classMouse,    /* Mechanical or optical mouse     */
  200.         classTrackball;    /* Trackball     */
  201.         
  202.     integer = $$CountOf(AcclTable);    /* Number of tables for this device    */
  203.     array AcclTable {    /* Entries sorted by first value; must have    */                /* at least 0.0 and 1.0 tables    */
  204.         unsigned hex longint;    /* Acceleration provided by this table (Fixed) */
  205.         
  206.         integer = $$CountOf(AcclPoint);    /* Number of control points for this device    */
  207.         wide array AcclPoint {    /* Entries sorted by first value; implicit     */
  208.                 /* first entry (0.0, 0.0); at least one more    */
  209.                 /* entry required.     */
  210.             unsigned hex longint;    /* Device speed (inches per second) (Fixed)     */
  211.             unsigned hex longint;    /* Cursor speed (inches per second) (Fixed)     */
  212.         };
  213.     };
  214. };
  215. The identifier for this 'accl' resource is stored in the first long word; this is either an OSType four character device identifier or an integer value specifying the device class. In either case, the device's identity is generally read from the device's register 1, as described below in the section "Extended Apple Mouse Protocol." The Cursor Device Manager first tries to match against the specific device identifier, then against the more general class.  Each 'accl' resource can contain a number of acceleration tables for different acceleration values; each table contains a number of entries which match a particular device speed to a particular cursor speed.  An 'accl' resource must contain at least two acceleration tables, one for an acceleration of 0.0 and one for an acceleration value of 1.0.  When an acceleration value is set for a particular device, the acceleration table is calculated by interpolating between the two nearest tables from the 'accl' resource.  There is an implicit entry in each acceleration table of (0.0, 0.0), which indicates that the cursor should not move if the device does not.  At least one additional entry is required; the Cursor Device Manager will use the table entries to figure the cursor movement by using the device movement to interpolate based on the specified movement control points.
  216. Availability Of The Cursor Device Manager
  217. The Cursor Device Manager was introduced in the ROMs of Macintoshes introduced in February, 1993.  It may be installed via software on any Macintosh.  To check to see if the Cursor Device Manager is available, you should use the standard TrapAvailable routine to check to see if its trap is implemented.  The Cursor Device Manager trap is $AADB, making it a toolbox trap, trap number $2DB.
  218. Compatibility
  219. When the Cursor Device Manager is installed, all Apple mouse drivers use its interface to move the cursor; this means that the low memory globals such as Mouse and RawMouse are no longer used.  While a compatibility mode keeps drivers which still modify these globals continue to work, the cursor position can no longer be read from these globals.
  220. Apple Devices
  221. Classic Apple Mouse Protocol
  222. The original Apple mouse protocol has allowed for mice with a resolution of 100 or 200 units per inch with 7 bit accumulation of relative movement with one or two buttons. Handler ID 1 was used to indicate 100 cpi operation; handler 2 to indicate 200 cpi operation. All data is transferred through register 0 in the following format:
  223. Figure 1–Classic Mouse Register 0 Format
  224. Where relative motion in each axis is accumulated until fetched with a talk register 0 command sent by the host. The X value represents left-to-right motion, the Y value holds accumulated forward-to-back motion.
  225. Extended Apple Mouse Protocol
  226. In order to be able to take advantage of the higher movement resolution support available with the Cursor Device Manager, an extended mouse protocol has been defined; this allows a device to communicate up to 16 bits of movement data with each polling and allows a standard device to communicate the state of up to 8 buttons. In addition, the new format allows each device to communicate its exact type, resolution and class. This new format applies to all relative devices at default address 3, handler ID 4.
  227. During startup or after a reset of the ADB bus, devices which power up at default address 3 with handler ID 1 will be switched to handler ID 4 with a listen register 3 command.  If the device accepts the switch and reports the new handler ID of 4 back in response to a talk register 3 command, all subsequent communication with the device will be assumed to follow the extended mouse protocol.  Currently, the ADB manager makes an additional check, making sure that a talk register 1 returns 8 bytes (the format of register 1 is specified below).  If a device accepts a handler ID change but does not return 8 bytes from register 1, it is assumed to not actually be an extended mouse protocol device and is switched back to its original handler ID.
  228. All movement and button data still passes through register 0, which can now hold between 2 and 5 bytes, where 2 bytes provides the device with the data transfer capability of the original mouse protocol and additional bytes allow added resolution and buttons.
  229. Bytes 0 and 1 of register 0 have the same format as they did in the classic mouse protocol, communicating the state of the first two buttons and the low order 7 bits of the accumulated motion in the X and Y axes.  There can be up to 3 bytes of additional information: each one of these bytes can communicate the state of 2 more buttons and add 3 higher order bits of resolution to each of the X and Y axes. The format of each additional byte is:
  230. Figure 2–Format Of Additional Register 0 Bytes For Extended Mouse Protocol
  231. As a specific example, in a maximal 5 byte transmission, the data would be transferred in this format:
  232. Bit #:    7    6    5    4    3    2    1    0    
  233. Byte 0:    b0    y06    y05    y04    y03    y02    y01    y00    
  234. Byte 1:    b1    x06    x05    x04    x03    x02    x01    x00    
  235. Byte 2:    b2    y09    y08    y07    b3    x09    x08    x07    
  236. Byte 3:    b4    y12    y11    y10    b5    x12    x11    x10    
  237. Byte 4:    b6    y15    y14    y13    b7    x15    x14    x13    
  238.  
  239. Table 2–Format Of A 5 Byte Register 0 Data Transfer
  240. Where bn indicates the status of button n and xaa or ybb indicates the value of bit aa or bb of the X or Y movement.
  241. In addition, register 1 is used in the extended mouse protocol to provide some general information about the device.  Register 1 is 8 bytes long and is formatted in this way:
  242. Byte range    Format    
  243. 0-3    Unique device identifier    
  244. 4-5    Device resolution in units/inch    
  245. 6    Device class (Mouse, trackball, etc.…)    
  246. 7    Number of buttons (0-8)    
  247.  
  248. Table 3–Format Of Extended Mouse Protocol Register 1
  249. The unique device identifier is intended to be a four character ASCII identifier similar to the OSType identifiers used as types and creators in the Macintosh file system; they can be registered using the same mechanism used to register creator types. A developer should only use a device identifier in this field if they have obtained a registration for that identifier's use as a creator from Apple.
  250. The device class is a value which is used to identify the type of device and to control the acceleration curve used for that device.  The currently defined constants include:
  251. Device constant    Device type    
  252. 0    Tablet device (absolutely positioned)    
  253. 1    Mouse    
  254. 2    Trackball    
  255.  
  256. Table 4–Currently defined device classes
  257. There currently isn't any mechanism for developers to create or register device classes; if a developer needs a device class not available from Apple, the only alternative available currently is not to use the handler ID 4 extended mouse protocol, instead using a custom handler ID and custom driver software.
  258. Apple Keyboard protocol
  259. The Apple keyboards have a simple data transfer protocol.  Register 0 is used to inform the host as keys are depressed and released; register 2 is used to communicate the state of the modifier keys and to control the LED indicators on the extended keyboards.
  260. The format of register 0 is:
  261. Figure 3–Keyboard Register 0 Format
  262. Register 0 can communicate up to two key transitions at once.  Each transition consists of a key code and a key released bit, which is 0 for key depressions and 1 for key releases.  The key codes are described in Inside Macintosh volume V, pages 191-192.  The special case is the reset key, which returns the value $7F7F in register 0 when it is depressed and $FFFF when released; thus, it uses both key code positions within register 0.
  263. The format of register 2 is:
  264. Figure 4–Keyboard Register 2 Format
  265. The current state of the keys listed in figure 4 is available in bits 6-14 of register 2, if those keys exist on the keyboard being examined.  Bits 0-2 hold the current state of the LEDs on the extended keyboard; the states of these LEDs can be changed by sending the keyboard a listen register 2 command.  Note that key transition events are generated in register 0 for modifier keys, as they are for all other keys; these keys are available in register 2 in addition to their status being transmitted through register 0.
  266. Miscellany 
  267. Licensing
  268. The Apple Desktop Bus is patented.  In order to build an ADB device, you will need to get a license from Apple.  Contact:
  269. Apple Software Licensing
  270. Apple Computer, Inc.
  271. 20525 Mariani Avenue, M/S 38-I
  272. Cupertino, CA       95014
  273. (408) 974-4667
  274. AppleLink: SW.LICENSE
  275. Internet: SW.LICENSE@applelink.apple.com
  276. The license is available for a nominal fee in most cases, and the licensing package includes the latest version of the ADB spec., which is the definitive reference to the bus.
  277. Further Reference:
  278. •    The Apple Desktop Bus specification, revision F.
  279. •    Inside Macintosh, Volume V, chapter 20, "The Apple Desktop Bus"
  280. •    Guide to the Macintosh Family Hardware, Second Edition, Chapter 8, "Apple Desktop Bus"
  281. xHRˇ ˇˇˇˇRH†Ç
  282. /ZÅ#
  283.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  284. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  285. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  286. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  287. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  288.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  289. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  290. HR.°dONLNdçZ†(õZ0ADB–The Untold Story : Space Aliens Ate My Mouse
  291. °dONLNd1üZÆö*Hardware
  292. °dONLNd;∫ZΔè* Written by:°dONLNdG∫¢Δ)HTim Dierks, Jim Mensch°dONLNd^∫‹Δ(√‹ January 1994°dONLNdkΔZ“õ(œZOriginally by:°dONLNdzΔ¢“,)HCameron Birse, Rich Kubota°dONLNdïfiZÍ¢(ÁZThis Technical °dONLNd§fi¢Í)HJNote explains a number of esoteric and unknown issues concerning the Apple°dONLNdÔÍZˆ∏(ÛZJDesktop Bus (ADB).  It incorporates material from the original version of °dONLNd9Í∏ˆ(Û∏this note, along with°dONLNdOˆZ|(ˇZa large °dONLNdWˆ|)"Vamount of new information, and is intended to detail information concerning all levels°dONLNdÆZg( Zof °dONLNd±g)
  293. Ythe ADB, from the hardware to the application usage level.  This note is supplementary to°dONLNd Z¥(Zthe information in °dONLNd¥Ö)Z&The Guide To Macintosh Family Hardware°dONLNdDÖΩ)—  and in the °dONLNdPΩ›)8Apple °dONLNdV›)  Desktop Bus°dONLNdbZ&ó(#Z
  294. Specification°dONLNdoó&Ó)=F. The information in the specification is the most accurate source of °dONLNdµÓ&(#Ó    data, and°dONLNdø&Z2…(/ZTunless it is specifically refuted, it should be treated as the authoritative source.°dONLNd2Z>è* Changes °dONLNd2è>)5since October 1991:°dONLNd/2>)u7  This note has been rewritten; new information appears"2 °dONLNdg>ZJ(GZXthroughout the document.  In particular, the Cursor Device Manager is discussed in this °dONLNdø>J(Gnote"> °dONLNdƒJZVÌ(SZUfor the first time. The information regarding bugs fixed in System 6.0.4 was omitted."J °dONLNdbZnÄ*Topics°dONLNd!nuzy+ •°dONLNd#n~z2)    #A discussion of ADB hardware issues°dONLNdGzuÜy(Éu•°dONLNdIz~Üÿ)    EInformation on the ADB protocol, including a detailed description of °dONLNdézÿÜÊ(Éÿthe°dONLNdíÜ~í9(è~&relocation and autopolling mechanisms.°dONLNdπíuûy(õu•°dONLNdªí~ûx)    1The recommended method of ADB driver installation°dONLNdÌûu™y(ßu•°dONLNdÔû~™Z)    +Documentation for the Cursor Device Manager°dONLNd™u∂y(≥u•°dONLNd™~∂∑)    @Description of the data formats used by Apple mice and keyboards°dONLNd^∂u¬y(øu•°dONLNd`∂~¬ˇ)    How to get an ADB license ŒXŒ
  295. °dONLNdzÁZˆ›(ÛZThe ADB Hardware
  296. °dONLNdãZä*The ADB °dONLNdìä)0Ris a simple serial bus with collision detection.  A common implementation platform°dONLNdÊZé(Z?for the protocol is a simple microcontroller; a 2 MHz Motorola °dONLNd%é(é68HC11 has been used with°dONLNd?Z&I(#Z1success, although any number of microcontrollers °dONLNdpI&)Ô)would do a more than adequate job.  The 2°dONLNdö&Z2•(/ZCMHz clock seemed to be close to minimal for this application.  The °dONLNd›&•2(/•bus has a relatively low°dONLNdˆ2Z>·(;ZObandwidth; given the packet structure, the theoretical maximum bandwidth is on °dONLNdE2·>(;· the order of°dONLNdR>ZJ8(GZ.100 - 200 bytes/second.  In practice, the bus °dONLNdÄ>8J)fi2is not suitable for data transfer applications; it°dONLNd≥JZV˝(SZZserves well as a general purpose input device bus, but high data rates will not work well.°dONLNdbZn°*In general, the °dONLNdb°n)GNtiming for the ADB is fairly tolerant of small variances; however, many recent°dONLNdmnZz(wZXMacintoshes are more demanding than their predecessors. For this reason, devices should °dONLNd≈nz(wbe°dONLNd»zZÜì(ÉZDtested on a wide range of machines; the best test for compliance is °dONLNd     zìÜ(Éìtesting.  Specifically, the Tlt°dONLNd    ,ÜZí;(èZ/(stop to start time) parameter has become much °dONLNd    [Ü;í)·1less tolerant in recent Macintoshes; fairly close°dONLNd    çíZûm(õZ=adherence to its 200 µs timing is important.  In particular, °dONLNd     ímû(õm"devices which respond more rapidly°dONLNd    ÌûZ™ñ(ßZEthan the 140 µs minimum delay will often fail to initialize properly. ¿X¿
  297. *.9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’ˇ1) of 18(ÎZHardwareˇ°¿Ù%%DSIDICT:_cv
  298. currentdict /bu known {bu}if
  299. userdict /_cv known not{userdict /_cv 30 dict put}if
  300. _cv begin
  301. /bdf{bind def}bind def
  302. currentscreen/cs exch def/ca exch def/cf exch def
  303. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  304. /ss{//cf //ca //cs setscreen}bdf
  305. /stg{ss setgray}bdf
  306. /strgb{ss setrgbcolor}bdf
  307. /stcmyk{ss cvcmyk}bdf
  308. /min1{dup 0 eq{pop 1}if}bdf
  309. end
  310. currentdict /bn known {bn}if
  311. †ø*HRˇ ˇˇˇˇRH
  312. HR,Times
  313. .+6-Macintosh Technical Notes /4/˘
  314. °dONLNdH6T…*$!It is important that your device °dONLNd!H…T¯)ì>be fairly tolerant of problems on the bus; if a command packet°dONLNd`T6`á(]6begins but never °dONLNdqTá`¯)QKseems to complete, your device should time out rather than hang; the design°dONLNdΩ`6l0(i66of the bus and its connectors means that there can be °dONLNdÛ`0l¯)˙*occasional glitches in the connection with°dONLNdl6xk(u6Dthe host, and you should try to be as tolerant of these as possible.°dONLNddÑ6êÙ*'Because the ADB bus is open collector, °dONLNdãÑÙê¯)æ6collisions can be detected when a device is attempting°dONLNd¬ê6úÆ(ô6to drive the bus high and °dONLNd‹êÆú¯)xDanother device pulls it low.  This means that whenever the device is°dONLNd!ú6®u(•6Adriving the bus high, it should be watching to make sure the bus °dONLNdbúu®¯(•uis actually high; if the bus°dONLNd®6¥À(±6goes low, some other device is °dONLNdû®À¥¯)ï?sending at the same time. When a device detects a collision, it°dONLNdfi¥6¿3(Ω66should immediately stop transmitting; this means that °dONLNd¥3¿¯)˝)if two devices are colliding, one of them°dONLNd>¿6Ãò(…6Iwill detect the collision, while one will not.  This is because a device °dONLNdá¿òï(…òcan only detect the°dONLNdõÃ6ÿ‹(’6^collision if it is driving the bus high and another device drives it low.  The device driving °dONLNd˘Ã‹ÿ¯(’‹it low°dONLNdÿ6‰{(·6has no way to °dONLNdÿ{‰¯)EStell that there was a collision, as the bus follows it.  Since the detecting device°dONLNdb‰6p(Ì6Eimmediately stops transmitting, the other device will not detect the °dONLNd߉p¯(Ìpcollision.  Thus, if there are°dONLNdΔ6¸>(˘6a °dONLNd»>¸¯)Znumber of devices transmitting on the bus, only one of them will complete its transmission°dONLNd#¸6÷(6!without detecting the collision, °dONLNdD¸÷¯)†6unless the unlikely occurrence of more than one device°dONLNd{6(6(transmitting exactly the same data with °dONLNd£¯)À/the same timing occurs, and neither detects the°dONLNd”6 b(6
  315. collision.°dONLNdfi,68∑*QThe ADB is not particularly tolerant of devices being connected and disconnected °dONLNd/,∑8¯(5∑
  316. while the bus°dONLNd=86DD(A69is live. There isn't any software architecture to detect °dONLNdv8DD¯(AD"the presence of new devices or the°dONLNdôD6PÁ(M6%absence of old ones; furthermore, on °dONLNdæDÁP¯)±5some CPUs, the motherboard is not well protected from°dONLNdÙP6\;(Y67voltage transients on the ADB connector; plugging in a °dONLNd+P;\¯(Y;&device while the Macintosh is on could°dONLNdR\6h¿(e6Scause damage to the ADB transceiver or other portions of the Macintosh's circuitry.°dONLNd¶t6ÄÔ*\On some portable Macintoshes, the voltage characteristics are not exactly what is specified °dONLNdtÔį(}Ôin°dONLNdÄ6å(â6/the ADB spec.  Clearly, power is very valuable °dONLNd4Äå¯)‚/on all portable computers, so if your device is°dONLNddå6òb(ï6    targeted °dONLNdmåbò¯),Htowards portable use, you should be extremely careful to keep your power°dONLNd∂ò6§(°6*consumption as low as possible; while the °dONLNd‡ò§¯)—0ADB can supply the full voltage specified in the°dONLNd    §6∞£(≠6Dspec., drawing this much power will lead to much more rapid battery °dONLNd    U§£∞¯(≠£draining. On the°dONLNd    f∞6º˙(π6#PowerBook 140 and 170, there was a °dONLNd    â∞˙º¯)ƒ1specific problem which caused the low-level input°dONLNd    ªº6»(≈6-voltage to go above the specified maximum of °dONLNd    Ëº»¯)‹/0.8 volts; it commonly came close to 1.5 volts.°dONLNd
  317. »6‘°(—6MThis has caused problems for some third-party devices; it has been corrected °dONLNd
  318. e»°‘¯(—°on all more recent°dONLNd
  319. x‘6‡F(›67machines. There is a recommended service procedure for °dONLNd
  320. Ø‘F‡¯(›F%repairing this problem available from°dONLNd
  321. ’‡6Ïp(È6CApple Service representatives, should this be a problem for a user.°dONLNd ¯6v*
  322. Soft Power°dONLNd $6÷*SOn Macintoshes with software power control, the machine can be turned on by an ADB °dONLNd w÷¯(÷device.°dONLNd Ä6(Z(%6<This is accomplished by momentarily connecting pin 2 on the °dONLNd ºZ(¯(%ZADB connector (reserved) to pin°dONLNd ‹(64Ü(164 (ground).  Pin °dONLNd Ì(Ü4¯)PK2 should be kept grounded until pin 3 (+5 volts) comes up to power, letting°dONLNd 946@∏(=6you know that the machine °dONLNd S4∏@¯)Ç>has actually come on.  Some Macintoshes do not have soft power°dONLNd í@6Lw(I6Ecapabilities; on these machines, grounding pin 2 will have no effect.
  323. °dONLNd ÿX6g≤*The ADB Protocol
  324. °dONLNd Ès6k*    Registers°dONLNd Ûã6óÜ*HEach ADB device has four logical registers; the host can ask the device °dONLNd
  325. ;ãÜó¯(îÜto talk or listen on each°dONLNd
  326. Uó6£§(†6one of these registers; °dONLNd
  327. m󧣯)nCa talk command asks the device to output the stored value from that°dONLNd
  328. ±£6ØÉ(¨6register; a listen °dONLNd
  329. ƒ£Éد)MMcommands asks the device to accept a new value for that register.  A register ¿4¿˘
  330. (’62) of 18)∫9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇBHRˇ ˇˇˇˇRH
  331. HR,Times
  332. .+Z-Developer Technical Support(-Á January 1994 /X/
  333. °dONLNd<ZHl(EZ:can contain between 2 and 8 bytes.  Some of the registers °dONLNd:<lH(El%have predefined functions: register 0°dONLNd`HZT⁄(QZis used as the primary data °dONLNd|H⁄T)ÄGtransfer register for most devices; it is this register which is polled°dONLNdƒTZ`z(]Zby the °dONLNdÀTz`) Winput mechanism (as described below).  Register 1 has no specified use; it is available°dONLNd#`ZlJ(iZ2for any use the device might require.  Register 2 °dONLNdU`Jl)*has no specified use for most devices; the°dONLNdÄlZx,(uZ+ADB specification does define an "extended °dONLNd´l,x)“2address device" protocol for register 2 on devices°dONLNdfixZÑ(ÅZ?at address 1, but this is unused by most developers.  Register °dONLNdxÑ(Å!3 is used to identify devices and°dONLNd?ÑZê£(çZ@to separate devices which occupy the same address, as discussed °dONLNdÑ£ê(ç£in "Address Resolution"°dONLNdóêZú{(ôZbelow.°dONLNdû®Z¥*!Default addresses and handler IDs°dONLNd¿¿ZÂ*REach ADB device identifies its software interface with two constants; the default °dONLNd¿‚Ã(…‚ address and°dONLNdÃZÿß(’Zthe handler ID.  °dONLNd/Ãßÿ)MPThis pair uniquely identifies a device's software interface; the default address°dONLNdÄÿZ‰æ(·ZLusually specifies a device's general type (such as relative pointing device °dONLNdÃÿæ‰(·æor keyboard) while°dONLNdfl‰Zk(ÌZthe °dONLNd„‰k)Zhandler ID specified the particular data protocol this device uses for communication.  The°dONLNd>Z¸(˘Z*default address categories are as follows:°dONLNdi»Ò+nDefault°dONLNdqΔ Ù(ΔAddress°dONLNdz1 w)k Device Type" ¡5"˜" ˜  ¯ Æ°dONLNdá!⁄-‡(*⁄1°dONLNdâ!¸-Y)"Security & Dongles" ¡5" ˜  ¯ Æ"!˜ °dONLNdù-⁄9‡(6⁄2°dONLNdü-¸90)"    Keyboards"-˜ °dONLNd™9⁄E‡(B⁄3°dONLNd¨9¸Eì)" Relative pointing devices (mice)"9˜ °dONLNdŒE⁄Q‡(N⁄4°dONLNd–E¸Qü)"#Absolute pointing devices (tablets)"E˜ °dONLNdıQ⁄]‡(Z⁄5°dONLNd˜Q¸]ì)"Low speed data transfer devices"Q˜ °dONLNd]⁄i‡(f⁄6°dONLNd]¸i©)" Reserved (PowerBook Duo charger)"]˜ °dONLNd<i⁄u‡(r⁄7°dONLNd>i¸u®)"$Appliances (Miscellaneous catch-all)"i˜ °dONLNdeÅÿçû(äÿ"Table 1–Default address categories°dONLNdàôZ•í(¢Z The default °dONLNdîôí•)8Raddress is only a guide; there's no real reason a mouse can't be at address 7, but°dONLNdÁ•Z±n(ÆZ:default addresses are assigned on a category basis to try °dONLNd!•n±(Æn"to avoid the case where a user has°dONLNdD±ZΩj(∫Z9more than one device at a particular address; by putting °dONLNd}±jΩ(∫j&all the relative devices at address 3,°dONLNd§ΩZ…î(ΔZDcollisions will be avoided at address 3 for all users who have only °dONLNdËΩî…(Δîone relative pointing device.°dONLNd…Z’(“ZZWhile the bus is robust with respect to seperating devices which are at the same address, °dONLNda…’(“the°dONLNde’Z·‡(fiZJADBS driver loading mechanism, which is described blow, made it useful to °dONLNdØ’‡·(fi‡ try to avoid°dONLNdº·ZÌW(ÍZ6having several dissimilar devices at the same address.°dONLNdÛ˘Zr*8Default addresses and handler IDs are assigned by Apple °dONLNd+˘r(rSoftware Licensing when an ADB°dONLNdJZr(Z=license contract is completed.  Default address 0 is used by °dONLNdár(r!the ADB host; addresses 8 through°dONLNd©Ze(Z:15 are used as locations to dynamically locate devices at.°dONLNd‰)Z5*#Some devices support more than one °dONLNd    )5)∑4data protocol.  An example is the extended keyboard,°dONLNd    <5ZA≈(>Zwhich can be asked to °dONLNd    R5≈A)kHsend separate key codes for the left & right shift keys.  This change is°dONLNd    õAZM‡(JZaccomplished by changing °dONLNd    ¥A‡M)Ü=its handler ID to 3; the new handler ID reflects the new data°dONLNd    ÚMZYD(VZ0protocol.  If your device receives a request to °dONLNd
  334. "MDY)Í+change handler IDs (via a listen register 3°dONLNd
  335. NYZe'(bZ*command), it should only obey the request °dONLNd
  336. xY'e)Õ2if it knows how to speak the protocol specified by°dONLNd
  337. ´eZq>(nZ/the new handler ID.  For example, the extended °dONLNd
  338. ⁄e>q)‰,keyboard, when receiving a request to change°dONLNd qZ}€(zZhandler IDs, should accept °dONLNd "q€})ÅBthe change if it is going to ID 3 or some other ID it knows about,°dONLNd e}ZâÜ(ÜZ?and should thereafter report that ID as its own in response to °dONLNd §}Üâ(ÜÜtalk register 3 commands; if it°dONLNd ƒâZï(íZYreceives a request to change to handler ID $52, it should ignore it, as it does not know °dONLNd âï(íwhat°dONLNd "ïZ°G(ûZ/handler ID $52 implies, and continue to report °dONLNd QïG°)Ì+its original handler ID in response to talk°dONLNd }°Z≠¿(™Zregister 3 commands. ¿X¿
  339. *+9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’3) of 18(ÎZHardwareˇJHRˇ ˇˇˇˇRH
  340. HR,Times
  341. .+6-Macintosh Technical Notes /4/˘
  342. °dONLNdH6T*$.A special case is devices which emulate Apple °dONLNd.HT¯)‰*device protocols.  For example, you may be°dONLNdYT6`“(]6constructing a 17-button mouse °dONLNdxT“`¯)ú=for use by specially trained squid; it has a special software°dONLNd∂`6l`(i6    protocol °dONLNdø``l¯)*Rto allow it to convey the state of all 17 mouse buttons.  However, you may wish to°dONLNdl6xq(u6<emulate the Apple mouse protocol so your device can be used °dONLNdNlqx¯(uqas a one button mouse on°dONLNdgx6ÑÖ(Å6machines which °dONLNdvxÖѯ)OMdon't have your driver software installed.  Due to the software design of the°dONLNdƒÑ6êÇ(ç6
  343. ADB manager, °dONLNd—ÑÇê¯)LMif your device is at default address 3, it will have the default mouse driver°dONLNdê6úÑ(ô6Kinstalled as its driver at startup regardless of its handler ID; when your °dONLNdjêÑú¯(ôÑsoftware loads, you can°dONLNdÇú6® (•6[install a new driver for your device and tell it to begin talking the 17 button protocol.  °dONLNd›ú ®¯(• You have°dONLNdÊ®6¥†(±6two options: you can °dONLNd˚®†¥¯)jAhave your device power up with the default Apple mouse handler ID°dONLNd=¥6¿Ï(Ω6Y($01) or with your own handler ID as assigned by Apple Software Licensing.  If you power °dONLNdñ¥Ï¿¯(ΩÏup°dONLNdô¿6à(…61with the $01 handler ID, your software will have °dONLNd ¿ Ã¯)Í-to locate your device by trying to change the°dONLNd¯Ã6ÿî(’6Ghandler ID of each device which started out at address 3 to you custom °dONLNd?Ãîÿ¯(’îID, then reading the°dONLNdTÿ6‰](·6handler °dONLNd\ÿ]‰¯)'QID of that device back; if the change stuck, then you know you're talking to your°dONLNdƉ6ø(Ì6Pdevice, and can install your custom driver.  In addition, the command to change °dONLNd˛‰ø¯(Ìø handler IDs°dONLNd
  344. 6¸¿(˘6Ttold the device to begin using your custom protocol.  Alternatively, you could have °dONLNd^¿¸¯(˘¿ your device°dONLNdj¸6˚(6&power up with your custom handler ID; °dONLNdê¸˚¯)≈0this would make identifying your device somewhat°dONLNd¡6fl(6\easier, as your device could be identified by its special handler ID; you would have to use °dONLNdfl¯(flsome°dONLNd"6 ñ(6special command to °dONLNd5ñ ¯)`Ltell the device that you have installed the new driver and that it can begin°dONLNdÇ 6,c()6    speaking °dONLNdã c,¯)-Uthe custom protocol.  For example, you could use a talk register 1 to tell the device°dONLNd·,68´(56Othat you're ready for the 17 button data protocol.  Both approaches work well, °dONLNd0,´8¯(5´but the first one°dONLNdB86Dfi(A6Yis recommended; it ensures that the current protocol can always be determined by looking °dONLNdõ8fiD¯(Afiat the°dONLNd¢D6P(M6.current handler ID; however, it relies on all °dONLNd–DP¯)Œ1devices at that default address handling commands°dONLNdP6\{(Y6Fasking them to change to a different handler ID properly, as a device °dONLNdHP{\¯(Y{which incorrectly changes°dONLNdb\6h|(e6its handler ID °dONLNdq\|h¯)FJto your assigned ID would fool you into thinking it was your device.  This°dONLNdºh6t‰(q6Zdoesn't seem to be a large problem, but there could be some obscure devices with this bug.°dONLNd    Ä6å•*Address Resolution°dONLNd    *ò6§Ã*QAddress resolution is the process the ADB manager uses to separate devices which °dONLNd    {òç¯(°à   share the°dONLNd    Ö§6∞C(≠66same default address, so they power up shadowing each °dONLNd    ª§C∞¯(≠C)other at a particular address.  It relies°dONLNd    Â∞6ºê(π6Eon devices using collision detection to determine when there is more °dONLNd
  345. *∞꺯(πêthan one device at a°dONLNd
  346. ?º6»ç(≈6particular address.°dONLNd
  347. S‘6‡Î*&An ADB device's register 3 is 2 bytes °dONLNd
  348. y‘·¯)µ8long and includes 4 bits in which the address is stored.°dONLNd
  349. ≥‡6Ïd(È6@When the device receives a listen register 3 command, it should °dONLNd
  350. Û‡dϯ(Èd take its address from this 4 bit°dONLNd Ï6¯æ(ı6Qfield.  When it receives a talk register 3 command, it would be redundant to put °dONLNd eÏæ¯¯(ıæ the device's°dONLNd r¯63(67address in that field; the device's address is already °dONLNd ©¯3¯)˝(uniquely determined by the fact that the°dONLNd “6™(
  351. 6device is responding to °dONLNd Í™¯)tBthe talk register 3 command, which was sent to a specific address.°dONLNd .6´(6Instead, a random 4-bit °dONLNd F´¯)uFvalue should be returned in this field; this makes it easier to detect°dONLNd ç6([(%6?collisions between two devices responding to a talk register 3.°dONLNd Õ46@*)When a device receives a talk register 3 °dONLNd ˆ4@¯)Ã/command, it should send back all of register 3,°dONLNd
  352. &@6Lù(I6including the random °dONLNd
  353. ;@ùL¯)gKfield, and it should pay careful attention to collision detection. Should a°dONLNd
  354. áL6XÃ(U6Qdevice detect a collision when responding to a talk register 3 request, there is °dONLNd
  355. ÿLÃX¯(Uà   a special°dONLNd
  356. ‚X6d(a6.provision in the ADB protocol which says that °dONLNdXd¯)fi1the device should ignore the next listen register°dONLNdBd6pA(m63 °dONLNdDdAp¯) Vwhich asks it to change address. The next time the device receives a listen register 3°dONLNdõp6|l(y6    command, °dONLNd§pl|¯)6Qit should check to see if the handler ID field is set to $FE.  This is a reserved°dONLNdˆ|6à$(Ö63handler ID used to distinguish this type of listen °dONLNd)|$à¯)Ó,request; if the handler ID field is $FE, the°dONLNdVà6îÿ(ë6Wdevice should only change address if it has safely transmitted a complete packet since °dONLNd≠àÿî¯(ëÿits last°dONLNd∂î6†å(ù6Icollision.  Of course, the device should not adopt the handler ID of $FE. ¿4¿˘
  357. *84) of 18)∫9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇ∂HRˇ ˇˇˇˇRH
  358. HR,Times
  359. .+Z-Developer Technical Support(-Á January 1994 /X/
  360. °dONLNd<ZHÌ(EZHere is a summary of a typical °dONLNd<ÌH)ì>sequence where the host is attempting to separate two devices.°dONLNd_HZTˆ(QZWThere are two devices of the same type, which I will call Fred and Wilma, at address 3.°dONLNd∑`~lû+$=1) The host will send a talk register 3 command to address 3.°dONLNdıl~x÷* E2) Both Fred and Wilma will receive the command and begin to respond.°dONLNd;x~Ñ *  3) Even though they are sending °dONLNd[x Ñ)¢1the same data, and they begin sending at the same°dONLNdçÑ~ê¯(ç~Otime, they select different random numbers to insert into the "device address" °dONLNd‹Ñ¯ê(ç¯field of°dONLNdÂê~úfl(ô~register 3, bits 7-10.°dONLNd¸ú~®* V4) Wilma detects a collision while trying to send bit 7 and immediately stops sending.°dONLNdS®~¥Û* Q5) Fred does not detect a collision and completes his transmission of register 3.°dONLNd•¥~¿‡* 6) The host, seeing °dONLNdπ¥‡¿)bBthat a device has responded to its talk register 3, sends a listen°dONLNd¸¿~Ãg(…~4register 3 to address 3, asking the device there to °dONLNd0¿gÃ)È#move to address $F.  The handler ID°dONLNdTÃ~ÿˇ(’~Vfield is $FE, indicating that a device should not move if it has detected a collision.°dONLNd´ÿ~‰O* +7) Both Fred and Wilma receive the request.°dONLNd◊‰~ö* 98) Fred moves to address $F; however, Wilma does not, as °dONLNd‰ö(Ìöshe has been locked out of°dONLNd+~¸(˘~Smoving because she detected a collision while responding to her last talk register °dONLNd~¸(˘3°dONLNdĸ~∞(~command.°dONLNdâ~ã* 9) °dONLNdåã)
  361. SThe host sends a talk register 3 to address $F to ensure that a device moved there.°dONLNd·~ a(~.Fred responds, assuring the host he has moved.°dONLNd ~,–* G10) The host repeats the separation procedure, sending a talk register °dONLNdW –,()–3 to address 3,°dONLNdg,~8fi(5~followed by a listen °dONLNd|,fi8)`Bregister 3 to address 3 asking the device there to move to address°dONLNdø8~Dè(A~$E.°dONLNd√D~Pf* 211) This time, Wilma does not detect a collision, °dONLNdıDfP)Ë&as she is the only device remaining at°dONLNdP~\9(Y~&address 3, so she moves to address $E.°dONLNdC\~h* J12) The host sends yet another talk register 3 to address 3, but does not °dONLNdç\h(e    receive a°dONLNdóh~t•(q~>response, as there are no more devices remaining at address 3.°dONLNd÷t~Ä…* D13) The host relocates Wilma from address $E back to address 3 with °dONLNdt…Ä(}…a listen register 3°dONLNd.Ä~å    (â~command sent to address $E.°dONLNdKå~ò†* <14) The host moves on and repeats the process for address 4.°dONLNdà§Z∞l(≠Z9Each and every ADB controller isn't guaranteed to follow °dONLNd¡§l∞(≠l&this procedure precisely, but it gives°dONLNdË∞Zºü(πZa feeling for °dONLNdˆ∞üº)EFthe principle behind the address resolution process.  You may see some°dONLNd=ºZ»⁄(≈ZOimplementations moving devices many more times than is necessary; this is done °dONLNdåº⁄»(≈⁄ because some°dONLNdô»Z‘ÿ(—ZPdevices have been manufactured to tolerances close enough that not only do they °dONLNdÈ»ÿ‘(—ÿsend their bits°dONLNd˘‘Z‡(›Z^at exactly the same time and so cannot detect collisions with each other, but they select the °dONLNd    W‘‡(›same°dONLNd    \‡ZÏ∂(ÈZ@random numbers to transmit.  We recommend that you include some °dONLNd    ú‡∂Ï(È∂low tolerance device°dONLNd    ±ÏZ¯Ñ(ıZ    (such as °dONLNd    ∫Ïѯ)*Wa capacitor on your reset line) to ensure that various devices will respond differently°dONLNd
  362. ¯ZP(Z7and be able to detect their collisions with each other.°dONLNd
  363. JZù* Autopolling°dONLNd
  364. V(Z4Í*TAutopolling is the primary method via which the host fetches data from your device. °dONLNd
  365. ™(Í4(1Í
  366.  The basic°dONLNd
  367. µ4Z@í(=Z
  368. mechanism °dONLNd
  369. ø4í@)8Sis that the host repeatedly issues talk register 0 commands to your device; if your°dONLNd @ZL‰(IZdevice responds with data, it °dONLNd 1@‰L)ä@is passed to your device's driver, which should act on it as new°dONLNd rLZXq(UZdata.°dONLNd xdZp    *$This implies that register 0 should °dONLNd úd    p)Ø7be the primary data transfer register for most devices;°dONLNd ‘pZ|é(yZ registers 1 °dONLNd ‡pé|)4Qand 2 are usually only used for supplementary data to configure the device.  Most°dONLNd 2|Zà‡(ÖZdevice drivers have no need °dONLNd N|‡à)ÜAto issue commands to their device, as all necessary data has been°dONLNd êàZî·(ëZtransferred within register 0. ¿X¿
  370. *D9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’5) of 18(ÎZHardwareˇÿHRˇ ˇˇˇˇRH
  371. HR,Times
  372. .+6-Macintosh Technical Notes /4/˘
  373. °dONLNd<6H◊*!When a device wishes to transmit °dONLNd!<◊H¯)°<data, it should wait until a command is issued to it or some°dONLNd^H6Tã(Q6Iother device.  If, when this transmission is completing, it still wishes °dONLNdßHãT¯(Qãto transfer data (if the°dONLNd¿T6`(]6.command was sent to our device, it might have °dONLNdÓT`¯)·/fetched the data already,) it should assert SRQ°dONLNd`6l:(i65after the data portion of the command by holding the °dONLNdS`:l¯(i:&bus low for 300 µs after the stop bit.°dONLNd{l6xŸ(u6#This will alert the host that some °dONLNdûlŸx¯)£;device wishes to transmit data.  It will then begin polling°dONLNd⁄x6Ñå(Å6Hthose addresses which it knows hold devices.  If a device does not have °dONLNd"xåѯ(Ååany data, the host will°dONLNd:Ñ6êT(ç6move °dONLNd?ÑTê¯)Ton to the next address, asking each device in turn, until SRQ is no longer asserted,°dONLNdîê6ú(ô62indicating that all pending data has been fetched.°dONLNd«®6¥å*When an SRQ is °dONLNd÷®å¥¯)VMnot asserted, the host will continually poll the last device to send it data,°dONLNd$¥6¿Δ(Ω6Usending it talk register 0 commands periodically.  This is done under the assumption °dONLNdy¥Δ¿¯(ΩΔ that this is°dONLNdÜ¿6Ãm(…6
  374. likely to be °dONLNdì¿mï)7Wthe next place the user interacts; if the user types a character, she is very likely to°dONLNdÎÃ6ÿ±(’6Ptype another soon.  On current hosts, this can happen up to 150 times a second, °dONLNd;ñÿ¯(’±although it can°dONLNdKÿ6‰s(·6Bhappen much less frequently in some cases. If the device responds °dONLNdçÿs‰¯(·swith any data, the host will°dONLNd™‰6„(Ì6'call the device's driver with the data.°dONLNd“¸6Ó*%Your device should only respond with °dONLNd˜¸Ó¯)∏6data when sent a talk register 0 command if it has new°dONLNd.63(68data. If the status of the device has not changed since °dONLNdf3¯)˝,the last talk register 0, then it should not°dONLNdì6 g(6Arespond at all, allowing the bus to time out. This is useful for °dONLNd‘g ¯(gtwo reasons: first, it tends to°dONLNdÙ 6,g()6;reduce the demands on the host, as your driver need not be °dONLNd/ g,¯()gcalled when your device has°dONLNdK,68†(56nothing useful to say. °dONLNdb,†8¯)jBSecond, in some ADB implementations, the host can get "hung up" on°dONLNd•86D€(A6Xyour device if you always respond. For example, say that you have a device at address 4 °dONLNd˝8€D¯(A€which°dONLNdD6Pœ(M6 will always respond, regardless °dONLNd#DœP¯)ô>of whether it has new data, there is another device at address°dONLNdbP6\À(Y6Y7, and the system is currently autopolling address 2. If the device at address 7 asserts °dONLNdªPÀ\¯(YÀSRQ, the°dONLNdƒ\6h∫(e6Qsystem will begin looking through the addresses looking for the device which has °dONLNd\∫h¯(e∫
  375. data to send.°dONLNd$h6tW(q6;When it reaches your device at address 4, your device will °dONLNd_hWt¯(qW respond, although it has nothing°dONLNdÄt6Äø(}6Pnew to say. On some implementations, this will cause the host to repeatedly ask °dONLNd–tøÄ¯(}ø your device°dONLNd‹Ä6åÆ(â6for more data, and your °dONLNdÙÄÆå¯)xAdevice will continue responding. Meanwhile, device 7 is withering°dONLNd    6å6òª(ï6away at the end of the bus °dONLNd    Qåªò¯)Ö>and will never get serviced. What your device should do is not°dONLNd    êò6§Ï(°6*respond to the talk register 0, as it has °dONLNd    ∫òϧ¯)∂8no new data; this will allow all host implementations to°dONLNd    Û§6∞™(≠6Opass you by and reach the device at address 7 which needs the host's attention.°dONLNd
  376. Cº6»*.A useful summary of a reasonable algorithm is:°dONLNd
  377. r»Z‘^+$ •°dONLNd
  378. t»c‘Ï)    Wait for a command to begin°dONLNd
  379. ê‘Z‡^(›Z•°dONLNd
  380. í‘c‡Ú)    OIf the command is directed to my address, handle it.  If it is a talk register °dONLNd
  381. ·‘Ú‡¯(›Ú0°dONLNd
  382. „‡cÏå(Èc>command, only respond if there is new data waiting to be sent.°dONLNd "ÏZ¯^(ıZ•°dONLNd $Ïc¯`)    7At the end of the command, if there is data waiting to °dONLNd [Ï`¯¯)˝be sent, assert SRQ, regardless°dONLNd {¯cY(c1of who the original command was directed towards.°dONLNd ≠6*(
  383. 62This simple behavior will produce the appropriate °dONLNd fl*¯)Ù'responses and SRQ generation for proper°dONLNd 6°(6Obus functioning.  It shouldn't be necessary for your device to explicitly have °dONLNd V°¯(°any knowledge of°dONLNd g6(°(%6Qwhether it is the "active" device or not; a robust basic behavior will eliminate °dONLNd ∏°(¯(%°any need for such°dONLNd  (64q(16 information.°dONLNd ◊@6Lf*@As an optimization, all recent versions of the ADB manager will °dONLNd
  384. @fL¯(Ifnot automatically poll a device°dONLNd
  385. 7L6X¨(U6which does not have a °dONLNd
  386. ML¨X¯)vDdriver service routine installed.  In this case, they will switch to°dONLNd
  387. íX6dQ(a6;autopolling some other device, even if that device has not °dONLNd
  388. ÕXQd¯(aQ been recently communicated with.°dONLNd
  389. Ôd6p/(m65However, the host may poll a device, even if it does °dONLNd$d/p¯)˘+not have a service request, in order to try°dONLNdPp6|∏(y6to clear an SRQ on the bus. ¿4¿˘
  390. *\6) of 18)∫9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇ‡HRˇ ˇˇˇˇRH
  391. HR,Times
  392. .+Z-Developer Technical Support(-Á January 1994 /X/
  393. °dONLNd<ZHº(EZBus Initialization°dONLNdTZ`“*Bus initialization doesn't °dONLNd.T“`)xAwork exactly as it might seem from looking at some documentation.°dONLNdq`Zl_(iZ0A SendReset command is never sent to individual °dONLNd°`_l(i_$devices; rather, when a bus reset is°dONLNdΔlZx◊(uZHrequested, the ADB manager sends a SendReset command which is broadcast °dONLNdl◊x(u◊to all devices,°dONLNdxZÑu(ÅZ9causing them to reset themselves and go to their default °dONLNdWxuÑ(Åuaddresses and handler IDs.  The°dONLNdwÑZê(çZXrelocation and driver loading procedure will follow immediately after the reset command °dONLNdœÑê(çis°dONLNd“êZúq(ôZsent.
  394. °dONLNdÿ®Z∑≤* ADB Drivers
  395. °dONLNd‰√Zœ¬*Driver Installation°dONLNd¯€ZÁ°*AIn the past, the recommended way to install an ADB driver was to °dONLNd9€°Á(‰°install a resource of type,
  396. Courier°dONLNdTÁZÛÑ(ÒZ'ADBS'°dONLNdZËÑÙü)* with °dONLNd`ËüÙ)Nthe same resource ID as your device's default address in the system file which°dONLNdØÙZ˚(˝Z\held code to install the driver for the ADB driver, along with the driver itself.  When the °dONLNd Ù˚(˝˚system°dONLNdZ
  397. Œ(
  398. Zwas booted or when the °dONLNd)Œ
  399. µ)t0bus was reinitialized, the system would get the °dONLNdYµ fl)Á'ADBS'°dONLNd_fl
  400. )* resource and°dONLNdl
  401. Z&(Z*execute it, which would let your code set °dONLNdñ
  402. &)Ã3the driver for that device up.  Unfortunately, this°dONLNd Z%("Z system is not well designed for °dONLNdÍ%)ñ>the wide variety of devices available; the most prominent flaw°dONLNd)&Z2ä(/Z is that the °dONLNd5%ä1¥)0'ADBS'°dONLNd;&¥2,)*resources are indexed by °dONLNdT&,2)x2default address only; thus, there is no way to use°dONLNdá3Z?k(<Zthe °dONLNdã2k>ï)'ADBS'°dONLNdë3ï?Õ)*
  403. mechanism °dONLNdõ3Õ?)8Gto load drivers for two different devices at address 7, as there can be°dONLNd„?ZKÛ(HZ only one resource with ID 7.  A °dONLNd?ÛK)ôCfurther flaw is that it requires installation into the system file,°dONLNdGKZW{(TZwhich °dONLNdMK{W)!Qis not currently recommended for a number of reasons.  In any case, it has always°dONLNdüWZc·(`ZMrequired a special installation and deinstallation program and has been more °dONLNdÏW·c(`·
  404. than a little°dONLNd˙cZo∫(lZconfusing for users.°dONLNd{Zá
  405. *"Currently, the recommended method °dONLNd1{
  406. á)∞8is to supply the user with a system extension which will°dONLNdjáZìä(êZ
  407. load your °dONLNdtáäì)0Vdriver; this can either be a simple extension, or it can be contained within a control°dONLNdÀìZüπ(úZpanel, should your °dONLNdfiìπü)_Fdevice require some user interface for configuration.  Your code, when°dONLNd%üZ´9(®Z0loaded, should look for your device and install °dONLNdUü9´)fl2your driver for it. If your device is at a default°dONLNdà´Z∑ã(¥Z=address which is not shared with standard Apple devices, you °dONLNd≈´ã∑(¥ãdon't have to concerned with°dONLNd‚∑Z√¯(¿Z[what driver is installed for you by default; your device can just power up at its standard °dONLNd=∑¯√(¿¯address°dONLNdE√Zœ(ÃZ)with its handler ID.  Your extension can °dONLNdn√œ)¿5then locate your device's current address by indexing°dONLNd§–Z‹m(ŸZ8through all the known devices with the ADB manager call °dONLNd‹œm€»(Ÿm
  408. GetADBInfo();°dONLNdÈ–»‹)[ when you find a°dONLNd˙‹ZË (ÂZIdevice whose initial address and handler ID match your device's, you can °dONLNd    C‹ Ë( call°dONLNd    HËZÙÆ(ÚZ SetADBInfo()°dONLNd    TÈÆı≤)T °dONLNd    UÈ≤ı)Jto install your driver's completion routine to handle autopolled data from°dONLNd    †ıZï(˛Z your device.°dONLNd    ≠
  409. Z‹*KBecause your ADB driver is in a system extension which will not load until °dONLNd    ¯
  410. ‹(‹
  411. well into the°dONLNd
  412. Z%Δ("ZLsystem startup process, if your device is a standard one (a pointing device °dONLNd
  413. RΔ%("Δor keyboard) you°dONLNd
  414. c%Z1(.Z&might need to provide standard system °dONLNd
  415. â%1)π8functionality before your driver loads in order to allow°dONLNd
  416. ¬1Z=≤(:ZLthe user to interact with the system during the startup process.  This also °dONLNd 1≤=(:≤allows the user to use°dONLNd %=ZI·(FZyour device to control their °dONLNd B=·I)á?machine even if they don't have the software installed, such as°dONLNd ÇIZU≈(RZOwhen they are booting off of a floppy.  In this case, your device will need to °dONLNd —I≈U(R≈be able to emulate°dONLNd ‰UZa8(^Z)the Apple protocol for mouse or keyboard °dONLNd
  417. U8a)fi,devices until your software driver loads, as°dONLNd :aZm(jZ&discussed above in "Default Addresses °dONLNd `am)∫7and Handler IDs".  Until your driver is installed, your°dONLNd òmZyÃ(vZSdevice will be serviced by the default driver for this address; this means that if °dONLNd ÎmÃy(vÃyour device is at°dONLNd ˝yZÖö(ÇZ
  418. address 2 or °dONLNd
  419. yöÖ)@M3, even if it cannot emulate an Apple device, it must supply harmless data in°dONLNd
  420. XÖZëπ(éZMregister 0 until your driver loads and is installed, as the Apple ADB driver °dONLNd
  421. •Öπë(éπfor that address may°dONLNd
  422. ∫ëZùœ(öZinadvertantly receive the °dONLNd
  423. ‘ëœù)uHcontents of your register 0 and attempt to use it as input data.  If the°dONLNdùZ©±(¶Zdata in your field °dONLNd0ù±©)WHcaused effects such as the mouse button or shift key sticking down, this°dONLNdy©Zµ˝(≤Z"could cause problems for the user. ¿X¿
  424. *#9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’7) of 18(ÎZHardwareˇ"≤HRˇ ˇˇˇˇRH
  425. HR,Times
  426. .+6-Macintosh Technical Notes /4/˘
  427. °dONLNdH6TX*$If you °dONLNdHXT¯)"Puse the recommended procedure for handler IDs in this case, powering up with the°dONLNdXT6`à(]6Bappropriate Apple handler ID and switching to your custom ID when °dONLNdöTà`¯(]àyour driver loads, you°dONLNd±`6l;(i65will need to use ADB commands to find your device at °dONLNdÊ`;l¯(i;&startup.  You should index through the°dONLNd
  428. m6y¡(v6connected ADB devices with ,
  429. Courier°dONLNd(l¡x)ã GetADBInfo()°dONLNd4my)T °dONLNd5my¯).and if you find a device which has an original°dONLNddy6Ö’(Ç6Zaddress and handler ID which indicates that it might be your device, attempt to switch it °dONLNdæy’Ö¯(Ç’to your°dONLNdΔÜ6íó(è6handler ID by using °dONLNd⁄Öóë»)aADBOp()°dONLNd·Ü»í|)1* to send it a listen register 3 to change °dONLNd Ü|í¯)¥its handler ID.  (You will°dONLNd&í6ûã(õ6Hfirst need to read its register 3 with a talk register 3 command so you °dONLNdníãû¯(õãcan correctly copy the°dONLNdÖû6™y(ß6Gvarious flag bits in the register you send to the device.)  You should °dONLNdÃûy™¯(ßythen issue a talk register 3°dONLNdÈ™6∂Á(≥6Ycommand to the device and examine the response to see if the new handler ID was accepted °dONLNdB™Á∂¯(≥Áand°dONLNdF∂6¬Ë(ø6_reported back by the device; if so, you can be certain that this device is your device and you °dONLNd•∂ˬ¯(øËcan°dONLNd©√6œ`(Ã6
  430. then call °dONLNd≥¬`Œ¥)* SetADBInfo()°dONLNdø√¥œ•)T7 to install your driver as the handler for that device.°dONLNd˜‹6Ë√(Â6In the original method using °dONLNd€√ÁÌ)ç'ADBS'°dONLNd‹ÌË8)* resources, the °dONLNd*‹8˯)K&system could automatically reload your°dONLNdQË6Ù˚(Ò6,driver any time the bus was reinitialized.  °dONLNd}Ë˚Ù¯)≈5If your driver is loaded via a system extension there°dONLNd≥Ù6/(˝65isn't any way for the system to find your device and °dONLNdËÙ/¯)˘*driver and reconnect them after the bus is°dONLNd6 ∫(    6reinitialized and devices are °dONLNd1∫ ¯)ÑArelocated.  Thus, you've got to manually reconnect your driver to°dONLNds 6 (60your device each time the bus is reinitialized. °dONLNd£  ¯)÷1 Fortunately, there is a system provision for you°dONLNd’6%?("6>to be notified each time the bus is reinitialized; there is a °dONLNd?%¿("?low memory global called °dONLNd,¿$¯)ÅjADBProc°dONLNd5%61–(.6V(at address $6B8) which is a pointer to a procedure to be called just before and just °dONLNdã%–1¯(.–    after the°dONLNdï26>¬(;6Zbus is initialized.  When the procedure is called before the bus is initialized, register °dONLNdÔ1¬=–(;¬D0°dONLNdÒ2–>fi) is °dONLNdı2fi>¯)set to°dONLNd¸>6Jö(G60; after, it is set to °dONLNd>öJ¯)dB1.  When your extension loads and installs your driver, you should°dONLNdVK6W°(T6remember the value in °dONLNdlK°W≥)kthe °dONLNdpJ≥VÎ)jADBProc°dONLNdxKÎW¯)89 global and then install a pointer to a procedure of your°dONLNd≤W6c∂(`6own in that location; when °dONLNdÕW∂c¯)ÄFthis procedure is called, it should do its thing, then call through to°dONLNdd6pB(m66the next procedure in the chain, whose address was in °dONLNdJcBoz(mBjADBProc°dONLNdRdzp∂)8  before you °dONLNd^d∂p¯)<replaced it (if°dONLNdnp6|n(z6jADBProc°dONLNdvqn}ö)8< was equal to 0 before you installed, just return from your °dONLNd≤qö}¯(zöprocedure).  Don't°dONLNd≈~6ä≤(á6forget to preserve register °dONLNd·}≤â¿)|D0°dONLNd„~¿ä—) so °dONLNdÁ~—ä¯)>subsequent procedures can tell if they are being called before°dONLNd    &ä6ñÕ(ì6$or after the reinitialization.  The °dONLNd    JäÕñ¯)óAactions you take in the post-initialization case should basically°dONLNd    åñ6¢≠(ü6Nduplicate your original installation procedure, including looking through all °dONLNd    ⁄ñ≠¢¯(ü≠the devices for°dONLNd    Í£6Øœ(¨6!devices of your type and calling °dONLNd
  431. ¢œÆ#)ô SetADBInfo()°dONLNd
  432. £#Ø⁄)T) to install your driver for your devices.°dONLNd
  433. Aª6«W(ƒ69For history buffs, this is the second time we've changed °dONLNd
  434. zªW«¯(ƒWour recommended procedure for°dONLNd
  435. ò«6”w(–6 loading ADB °dONLNd
  436. §«w”¯)ANdrivers.  Initially, it was recommended that ADB drivers be loaded with INITs;°dONLNd
  437. Û‘6‡°(›6however, at the time, °dONLNd     ”°flŸ)kjADBProc°dONLNd ‘Ÿ‡›)8 °dONLNd ‘›‡¯)7did not exist, so when the Macintosh Portable came out,°dONLNd J‡6ÏB(È69INIT-handled devices had the fatal flaw of not reloading °dONLNd ɇBϯ(ÈB$their drivers when the Macintosh was°dONLNd ®Ï6¯z(ı6Eput to sleep and reawakened, since this procedure involved resetting °dONLNd ÌÏz¯¯(ızthe bus.  This cause us to°dONLNd ˘6“(6begin recommending the use of °dONLNd &˘“Â)úthe °dONLNd *¯Â)'ADBS'°dONLNd 0˘¯)*/resource, since in this way the driver could be°dONLNd `6˛(6)reloaded from the System file.  However, °dONLNd â˛)»the °dONLNd ç:)'ADBS'°dONLNd ì:¯)*%approach has so many major flaws that°dONLNd π6(6-we have stopped recommending it now that the °dONLNd ÊO)·jADBProc°dONLNd ÓO⁄)8 global has been introduced.  °dONLNd
  438. ⁄¯)ãAs far°dONLNd
  439.  6,r()6as I can tell, °dONLNd
  440. "r+™)<jADBProc°dONLNd
  441. * ™,á)80 has been available at least since System 6.0.4.°dONLNd
  442. [86DÇ(A6GFor true history buffs, or possibly for specialized applications, here °dONLNd
  443. ¢8ÇD¯(AÇis the description of the°dONLNd
  444. ºD6P`(N6'ADBS'°dONLNd
  445. ¬E`Q„)*resource functionality: the °dONLNd
  446. fiD„P
  447. )É'ADBS'°dONLNd
  448. ‰E
  449. Qï)*resource is loaded into the °dONLNdEïQ¯)àsystem heap by the°dONLNdR6^∂([6system and detached with °dONLNd,Q∂]&)ÄDetachResource()°dONLNd<R&^«)p".  The resource is then called by °dONLNd^Q«]‹)°JSR°dONLNdaR‹^Ô)ing °dONLNdeRÔ^¯)to°dONLNdh_6k(h6.the first byte of the resource. At this time, °dONLNdñ_k∏)—%the registers are set up as follows: °dONLNdª^∏jΔ)±A0°dONLNdΩ_Δk¯)
  450.  holds the°dONLNd»l6x](u6address °dONLNd–l]x})'of the °dONLNd◊k}wß) 'ADBS'°dONLNd›lßx¯)*Gresource data (although it is no longer in a resource handle, thanks to°dONLNd%y6ÖH(Ç6the °dONLNd)xHÑ∏)DetachResource()°dONLNd9y∏Öe)p' call); if a handle to the resource is °dONLNd`yeÖè)≠needed, °dONLNdhxèѯ)*RecoverHandle()°dONLNdxÜ6í+(è68can be called to retrieve it.  The low byte of register °dONLNd∞Ö+ë9)ıD0°dONLNd≤Ü9íØ) holds the ADB device's °dONLNd ÜØí¯)vcurrent address°dONLNd⁄í6ûº(õ6O(due to relocation, this might not be the same as the default address) and the °dONLNd)íºû¯(õº low byte of°dONLNd5ü6´\(®6    register °dONLNd>û\™j)&D1°dONLNd@üj´G)0 holds the handler ID of the device in question. ¿4¿˘
  451. (’68) of 18)∫9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇZHRˇ ˇˇˇˇRH
  452. HR,Times
  453. .+Z-Developer Technical Support(-Á January 1994 /X/
  454. °dONLNdHZW(TZThe Cursor Device Manager
  455. °dONLNdcZoÁ*SIn order to be able to manage an expanding set of relative movement devices, Apple °dONLNdmcÁo(lÁ has created°dONLNdyoZ{∏(xZBthe Cursor Device Manager, which is a software architecture which °dONLNdªo∏{(x∏provides a standard°dONLNdœ{Zá›(ÑZPinterface to devices of widely varying resolutions and capabilities.  This also °dONLNd{›á(Ñ›
  456. allows better°dONLNd-áZìò(êZ management °dONLNd8áòì)>Tof multiple relative devices on a single bus; in the old architecture, all connected°dONLNdçìZüP(úZ6devices shared a single button state and acceleration °dONLNd√ìPü)ˆ'curve, which became a problem for Apple°dONLNdÎüZ´(®ZWand for third-party device manufacturers.  The Cursor Device Manager provides a number °dONLNdBü´(®of°dONLNdE´Z∑É(¥Z
  457. calls for °dONLNdO´É∑))Vfinding, configuring, and manipulating relative devices connected to the bus.  It also°dONLNd¶∑Z√ó(¿Z
  458. supports the °dONLNd≥∑ó√)=Lnew extended mouse protocol, which is described below in the "Apple Devices"°dONLNd√Zœ(ÃZsection.°dONLNd    €ZÁ*Cursor Device Manager types°dONLNd%ÛZˇì*BThe Cursor Device Manager treats each relative or absolute device °dONLNdgÛìˇ(¸ìas a "Cursor Device".  Each°dONLNdÉZ Ω(    Zone is specified by a ,
  459. Courier°dONLNdôˇΩ )c
  460. CrsrDevRec°dONLNd£ ã)F which is defined as follows:
  461.     °dONLNd¡Z#◊( ZCrsrDevPtr = ^CrsrDevRec;°dONLNd€"Z-π*
  462. CrsrDevRec = RECORD°dONLNd,l7£+
  463. nextCrsrDev°dONLNd¸,Ω7˘)Q :CrsrDevRec^°dONLNd    ,D7Û)á#; ptr to next record in linked list°dONLNd.6lA£(>l whichCursor°dONLNd:6ΩA˛)Q
  464. :CrsrDataRec^°dONLNdH6DAfl)á; ptr to data for target cursor°dONLNdi@lKä(HlrefCon°dONLNdp@ΩKÂ)Q:LongInt°dONLNdy@DK≠)á; Application defined°dONLNdêJlUä(Rlunused°dONLNdóJΩUÂ)Q:LongInt°dONLNd†JDU≠)á; reserved for future°dONLNd∑^liÖ(fldevID°dONLNdΩ^Ωi‡)Q:OSType°dONLNd≈^DiÛ)á#; device identifier(from ADB reg 1)°dONLNdÍhlsû(pl
  465. resolution°dONLNdıhΩs€)Q:Fixed°dONLNd¸hDsÛ)á#; units/inch (orig. from ADB reg 1)°dONLNd!rl}î(zldevClass°dONLNd*rΩ}÷)Q:Char°dONLNd0rD}Û)á#; device class     (from ADB reg 1)°dONLNdU|láû(Ñl
  466. cntButtons°dONLNd`|Ωá÷)Q:Char°dONLNdf|DáÛ)á#; # of buttons     (from ADB reg 1)°dONLNdãÜlëä(élspare1°dONLNdíÜΩë÷)Q:Char°dONLNdòÜDëv)á
  467. ; reserved°dONLNd§öl•è(¢lbuttons°dONLNd¨öΩ•÷)Q:Char°dONLNd≤öD•≤)á; state of all buttons°dONLNd §lØî(¨lbuttonOp°dONLNd”§ΩØ!)Q:Array[0..8] of Char°dONLNd˧DØ’)á; action performed per button°dONLNdÆlπ£(∂l buttonTicks°dONLNdÆΩπ0)Q:Array[0..8] of LongInt°dONLNd+ÆDπ‰)á ; ticks when button last went up°dONLNdM∏l√û(¿l
  468. buttonData°dONLNdX∏Ω√0)Q:Array[0..8] of LongInt°dONLNdp∏D√fl)á; data for the button operation°dONLNdë¬lÕ∑( ldoubleClickTime°dONLNd°¬ΩÕÂ)Q:LongInt°dONLNd™¬DÕ–)á; device’s double click time°dONLNd»Ãl◊®(‘l acceleration°dONLNd’ÃΩ◊€)Q:Fixed°dONLNd‹ÃD◊≤)á; current acceleration°dONLNdÙ‡lΣ(Ël accelPoints°dONLNd‡ΩΗ)Q:Ptr°dONLNd‡DÎ)á'; Private: Ptr to array of  (dev_delta,°dONLNd0ÍDı∑*
  469. ;     slope, intercept)°dONLNdIÙlˇä(¸ldeltaX°dONLNdPÙΩˇ€)Q:Fixed°dONLNdWÙDˇ’)á; Private: accumulated deltas°dONLNdv˛l    ä(ldeltaY°dONLNd}˛Ω    €)Q:Fixed°dONLNdÑ˛D    {)á ; Private: °dONLNd벬    «)~"°dONLNdîlä(lerrorX°dONLNdõΩ€)Q:Fixed°dONLNd¢D’)á; Private: accumulated errors°dONLNd¡lä(lerrorY°dONLNd»Ω€)Q:Fixed°dONLNdœD{)á ; Private: °dONLNd‹¬«)~"°dONLNdfll'Ö($ldenom°dONLNdÂΩ'€)Q:Fixed°dONLNdÏD'¯)á$; Private: fraction of the errors to°dONLNd&D1£*
  470. ;     use next time°dONLNd)0l;ä(8lspread°dONLNd00Ω;€)Q:Fixed°dONLNd70D;)á&; Private: Number of samples to spread°dONLNda:DEô*
  471. ;     errors over°dONLNdtDlOè(LlnewData°dONLNd|DΩO÷)Q:Char°dONLNdÇDDOÓ)á"; Private: set when deltas are new°dONLNd¶NlYä(Vlspare2°dONLNd≠NΩY÷)Q:Char°dONLNd≥NDYv)á
  472. ; reserved°dONLNdæXZcn(`ZEND;
  473. °dONLNd√oZ{Ç*@The cursor controlled by this cursor device is described with a °dONLNd    nÇzœ(xÇ CrsrDataRec°dONLNd    oœ{“)M:
  474.     °dONLNd    áZí·(èZCrsrDataPtr = ^CrsrDataRec;°dONLNd    ,ëZúë*
  475. CrsrDataRec°dONLNd    8ëΩúÂ)c= RECORD°dONLNd    Bõl¶®(£l nextCrsrData°dONLNd    OõΩ¶˛)Q
  476. :CrsrDataRec^°dONLNd    ]õD¶≠)á; next in global list°dONLNd    u•l∞£(≠l displayInfo°dONLNd    Å•Ω∞—)Q:Ptr°dONLNd    Ü•D∞¡)á; reserved for future use ¿X¿
  477. (’Z9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’9) of 18(ÎZHardwareˇ∫HRˇ ˇˇˇˇRH
  478. HR,Times
  479. .+6-Macintosh Technical Notes /4/˘,
  480. Courier
  481.     °dONLNd<HGf+whereX°dONLNd<ôG∑)Q:Fixed°dONLNd< Gâ)á; horizontal position°dONLNd%FHQf(NHwhereY°dONLNd,FôQ∑)Q:Fixed°dONLNd3F Q)á; vertical position°dONLNdHPH[a(XHwhere°dONLNdNPô[∑)Q:Point°dONLNdUP [Ñ)á; the pixel position°dONLNdkZHea(bHisAbs°dONLNdqZôe¡)Q:Boolean°dONLNdzZ e„)á'; has been stuffed with absolute coords°dONLNd£dHo(lH buttonCount°dONLNdØdôo≤)Q:Char°dONLNdµd oŸ)á%; number of buttons currently pressed°dONLNd‹nHyu(vH    screenRes°dONLNdÊnôy¡)Q:Integer°dONLNdÔn yË)á(; Pixels per inch on the current display°dONLNdx6ÉJ(Ä6END;
  482. °dONLNdö6¶K*#<Most of the fields are fairly self-explanatory.  The fields °dONLNdYöK¶¯(£K$labeled as private at the end of the°dONLNd~¶6≤|(∞6
  483. CrsrDevRec°dONLNdàß|≥E)F( are used to manage cursor acceleration °dONLNd∞ßE≥¯)…!and shouldn't be modified by your°dONLNd“≥6øá(º6software.  Some °dONLNd‚≥áø¯)QNof the usage of the other fields will be explained below in the description of°dONLNd1ø6Àfi(»6#the cursor device manager routines.°dONLNdU◊6„Ò*Cursor Device Manager Routines°dONLNdtÚ6˛¶*CrsrDevNextDevice, New York°dONLNdÖÔ¶ˇ™)p:°dONLNdá˛6
  484. ⁄(6<Function CrsrDevNextDevice(VAR curDevice: CrsrDevPtr):OSErr;°dONLNdƒ6"ª*CrsrDevNextDevice()°dONLNd◊ª#¿)Ö °dONLNdÿ¿#¯);can be used to index through the various devices the Cursor°dONLNd$60
  485. (-6+Device Manager is aware of.  You pass it a °dONLNd?#
  486. /S)◊
  487. CrsrDevPtr°dONLNdI$S0’)F; initialize this variable to °dONLNdg#’/Í)Çnil°dONLNdj$Í0¯) to°dONLNdn16=(:6advance to the °dONLNd}1= )I$first device in the list, then call °dONLNd°0 <•)°CrsrDevNextDevice()°dONLNd¥1•=¯)Ö repeatedly, each°dONLNdΔ>6JÖ(G6time passing the °dONLNd◊=ÖIÀ)O
  488. CrsrDevPtr°dONLNd·>ÀJ˙)F  as it was °dONLNdÏ>˙J¯)/3last modified; when you have reached the end of the°dONLNd K6WË(T6)device list, the pointer returned in the °dONLNdIJËV')≤    curDevice°dONLNdRK'Wà)? parameter will be 0.°dONLNdhf6r•(o6CrsrDevNewDevice°dONLNdxc•s©)o:°dONLNdzr6~n(|6Function°dONLNdÇpnÄr)8 °dONLNdÉrr~–)2CrsrDevNewDevice(VAR ourDevice: CrsrDevPtr):OSErr;°dONLNd∂ã6óL(î6Call °dONLNdªäLñ )CrsrDevNewDevice()°dONLNdÕã ó˜)~  to create °dONLNdÿã˜ó¯)-6a new cursor device and link it into the device chain.°dONLNdó6£÷(†6YThe new device record will be initialized with values representing a standard one-button °dONLNdhó÷£¯(†÷mouse;°dONLNdo§6∞Å(≠6you should call °dONLNd£ÅØ))KCrsrDevSetAcceleration()°dONLNdó§)∞á)® for the device after °dONLNd≠§á∞¯)^creating it. A pointer to°dONLNd«±6Ωfi(∫6&the created device is returned in the °dONLNdÌ∞fiº)®    ourDevice°dONLNdˆ±ΩI)?
  489.  variable.°dONLNd…6’(“6+New cursor devices are created for all ADB °dONLNd,…’¯)ÿ.address 3 devices. This routine should only be°dONLNd[’6··(fi6Xneeded by devices which are connected though some other method, such as the serial port.°dONLNd¥Ì6˘º*CrsrDevDisposeDevice:°dONLNd ˘6”*
  490. ;Function CrsrDevDisposeDevice(ourDevice: CrsrDevRec):OSErr;°dONLNd6◊*[This routine disposes of a cursor device and unlinks it from the device chain.  This isn't °dONLNda◊¯(◊needed°dONLNdh6)ô(&6by most developers, °dONLNd|ô)¯)cDbut could be useful for non-ADB devices which might be connected and°dONLNd¡)65w(26
  491. disconnected.°dONLNdœA6Mà* CrsrDevMove:°dONLNd‹M6Yc*
  492. +Function CrsrDevMove(ourDevice: CrsrDevRec;°dONLNdY6eõ* 3                     deltaX,deltaY: LongInt):OSErr;°dONLNd<q6}ë*
  493. CrsrDevMove()°dONLNdIrë~·)[ accumulates the °dONLNdZq·} )PdeltaX°dONLNd`r ~")* and °dONLNdeq"}L)deltaY°dONLNdkrL~¯)*" values into the recorded movement°dONLNdé~6äÆ(á6Uof the device; the next time the cursor position is calculated, these deltas will be °dONLNd„~Æä¯(áÆfed through the°dONLNdÛä6ñk(ì6Bacceleration algorithm and used to move the cursor.  This routine °dONLNd    5äkñ¯(ìkshould be called by a relative°dONLNd    Tñ6¢Á(ü6(device driver with the data it receives °dONLNd    |ñÁ¢¯)±<from its device, even if the deltas are both zero; this lets°dONLNd    π¢6Æ®(´6Gthe acceleration algorithm properly calculate the appropriate motion.  °dONLNd
  494. ¢®Æ¯(´®This routine is ¿4¿˘
  495. (’610)
  496.  of 18)µ9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇHRˇ ˇˇˇˇRH
  497. HR,Times
  498. .+Z-Developer Technical Support(-Á January 1994 /X/
  499. °dONLNd<ZH (EZ^automatically called by the default driver for address 3 devices; you would only need to call °dONLNd^< H(E it if°dONLNddHZTÛ(QZyou were using a custom driver.°dONLNdÑ`Zlª*CrsrDevMoveTo:,
  500. Courier°dONLNdìlZxï*
  501. -Function CrsrDevMoveTo(ourDevice: CrsrDevRec;°dONLNd¡xZѱ* 1                       absX,absY: LongInt):OSErr;°dONLNdÛêZú√*CrsrDevMoveTo()°dONLNdë√ùé)i. sets the absolute position of the cursor to (°dONLNd0êéú™)ÀabsX°dONLNd4ë™ù±), °dONLNd6ê±úÕ)absY°dONLNd:ëÕù)).  The °dONLNdBëù)#    next time°dONLNdLùZ©»(¶Zthe cursor position is °dONLNdcù»©)nCcalculated, it will be moved to this absolute location.  This would°dONLNdß©Zµ‡(≤ZTnormally be used by a driver for an absolute pointing device to position the cursor.°dONLNd¸¡ZÕ≠*
  502. CrsrDevFlush:°dONLNd
  503. ÕZŸø*
  504. 3Function CrsrDevFlush(ourDevice: CrsrDevRec):OSErr;°dONLNd>ÂZÒº*CrsrDevFlush()°dONLNdLʺÚÎ)b@ causes the acceleration and motion algorithms to flush out all °dONLNdåÊÎÚ(ÔÎ their error°dONLNdòÚZ˛(˚Z&collection and motion deltas into the °dONLNdæÚ˛)∏6cursor position; it indicates that your device is done°dONLNdı˛Z
  505. %(Z(moving temporarily.  This may be useful °dONLNd˛%
  506. )À0for devices which can tell when they become idle°dONLNdN
  507. Z™(ZH(such as a stylus pointing device); if they call this routine when they °dONLNdñ
  508. ™(™become idle, it ensures°dONLNdÆZ" (Z$that all unused motion data will be °dONLNd“ ")≤6worked into the cursor position at the next time it is°dONLNd    "Z.å(+Z calculated.°dONLNd=ZIµ*CrsrDevButtons, New York°dONLNd#:µJπ)[:°dONLNd%IZUú(SZ.Function CrsrDevButtons(ourDevice: CrsrDevRec;°dONLNdTUZaï* -                        buttons: Char):OSErr;°dONLNdÇmZy *CrsrDevButtons()°dONLNdín z )p handles posting °dONLNd£m yQ)VmouseUp°dONLNd™nQzl)1 and °dONLNdØmly´)    mouseDown°dONLNd∏n´z∞)? °dONLNdπn∞z)events and also deals°dONLNdœ{Zás(ÑZwith °dONLNd‘{sá¥)@debouncing mouse clicks.  Pass the current button status in the °dONLNdz¥ÜÂ(Ñ¥buttons°dONLNd{Âá)1  parameter,°dONLNd'áZìÌ(êZgoing from bit 0 is button 0 °dONLNdDáÌì)ì;to bit 7 representing button 7.  For each button, a one bit°dONLNdÄìZü(úZ'represents down, a zero bit represents °dONLNdßìü)∂5up.  This routine debounces mouse clicks to keep them°dONLNd›üZ´¥(®ZKfrom looking like double clicks; if the button goes down less than 2 ticks °dONLNd(ü¥´(®¥after coming up, then°dONLNd>¨Z∏k(µZthe °dONLNdB´k∑™)    mouseDown°dONLNdK¨™∏¬)? will °dONLNdQ¨¬∏)Ebe ignored. Button up events are never ignored to avoid problems such°dONLNdó∏Zƒ˛(¡ZXas continuous scrolling which are confusing and difficult for the user to deal with.  A °dONLNdÔ∏˛ƒ(¡˛device°dONLNdˆƒZ–(ÕZ)driver should call this routine any time °dONLNdƒ–)ø6it gets a data packet; this routine deals with keeping°dONLNdV–Z‹ï(ŸZ=track of whether the button state has changed.  This routine °dONLNdì–ï‹(Ÿïautomatically calls routines°dONLNd∞›ZÈú(ÊZinstalled with °dONLNdø‹úË)BCrsrDevButtonOp()°dONLNd–›È)w.°dONLNd“¯Z–(ZCrsrDevButtonDown°dONLNd„ı–‘)v:°dONLNdÂZ‚(Z8Function CrsrDevButtonDown(ourDevice: CrsrDevRec):OSErr;°dONLNdZ(fl*CrsrDevButtonDown()°dONLNd1fl))Ö     posts a °dONLNd:(E)'    mouseDown°dONLNdCE))?. event if this is the first button to go down °dONLNdq))…for°dONLNdu)Z5ú(2ZFthis device.  It is called by the standard button operation routines; °dONLNdª)ú5(2úyou should need to call it°dONLNd÷5ZAF(>Z2only if you use a custom button operation routine.°dONLNd        PZ\¿*CrsrDevButtonUp°dONLNd    M¿]ƒ)f:°dONLNd    \Zh‘(fZ6Function CrsrDevButtonUp(ourDevice: CrsrDevRec):OSErr;°dONLNd    QtZÄ—*CrsrDevButtonUp()°dONLNd    bu—Å)w posts °dONLNd    iuÅ˘)a °dONLNd    kt˘Ä*)    mouseUp°dONLNd    ru*Å)15 event if this is the last button to come up for this°dONLNd    ®ÅZçP(äZ7device.  It is called by the standard button operation °dONLNd    flÅPç)ˆ,routines; you should need to call it only if°dONLNd
  509. çZô$(ñZ*you use a custom button operation routine. ¿X¿
  510. *?9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’ 11)
  511.  of 18(ÎZHardwareˇ^HRˇ ˇˇˇˇRH
  512. HR,Times
  513. .+6-Macintosh Technical Notes /4/˘
  514. °dONLNd<6Hü*CrsrDevButtonOp:,
  515. Courier°dONLNdH6TÔ*
  516. ?Function CrsrDevButtonOp(ourDevice: CrsrDevRec; btnNo: Integer;°dONLNdQT6`Ô* ?                         opCode: Integer; data: LongInt):OSErr;°dONLNdël6x≠*CrsrDevButtonOp()°dONLNd¢m≠y")w sets a new operation °dONLNd∏m"y¯)u*to be associated with a particular button.°dONLNd‰y6ÖY(É6btnNo°dONLNdÈzYÜ\)# °dONLNdÍz\ÜÁ)may range from 0 to 7, and °dONLNdyÁÖ)ãopCode°dONLNd zܯ)*1 specifies what operation to use.  The data field°dONLNd=á6ì∞(ê6specifies a parameter for °dONLNdWá∞ìh)z&the operation you are setting for the °dONLNd}Ühí√)∏
  517. kButtonCustom°dONLNdäá√ì¯)[  operation.°dONLNdóî6†K(ù6The °dONLNdõìKüu)opCode°dONLNd°îu†])*0 parameter may have one of the following values:°dONLNd“¨Z∏ß(∂Z kButtonNoOp°dONLNdfi¨Í∏(µÍ    No action°dONLNdÈ∏Zƒÿ(¬ZkButtonSingleClick°dONLNd¸∏̓Q(¡ÍNormal mouse button°dONLNdƒZ–ÿ(ŒZkButtonDoubleClick°dONLNd$ƒÍ–ª(ÕÍ,Click, release, and click again when pressed°dONLNdR–Z‹ (⁄ZkButtonClickLock°dONLNdc–Í‹ó(ŸÍ%Click on press, release on next press°dONLNdä‹ZË—(ÊZkButtonCharStroke°dONLNdú‹ÍËd(ÂÍUnimplemented, reserved°dONLNdµËZÙÿ(ÚZkButtonAppleScript°dONLNd»ËÍÙd(ÒÍUnimplemented, reserved°dONLNd·ÙZµ(˛Z
  518. kButtonCustom°dONLNdÔÙÍ«(˝Í/Call a custom procedure; data holds its address°dONLNd!
  519. 6g(6
  520. Using the °dONLNd+ g¶)1    btnCustom°dONLNd4
  521. ¶ò)?3 operation will cause a procedure whose address is °dONLNdg
  522. ò¯)Úpassed in data to be°dONLNd|6%Ö("6called whenever °dONLNdåÖ%¯)OMthis button changes state.  The procedure takes the following parameters: the°dONLNd⁄&62~(/6address of the °dONLNdÈ%~1ƒ)H
  523. CrsrDevRec°dONLNdÛ&ƒ2j)F$ record for its device is passed in °dONLNd&j2í)¶    register °dONLNd %í1†)(A2°dONLNd"&†2¯); the button being°dONLNd536?–(<6#pressed or released is in register °dONLNdX2–>fi)öD3°dONLNdZ3fi?˝).  The °dONLNda3˝?¯)5new state of the button will already have been filled°dONLNdó@6L∑(I6into the buttons field in the °dONLNdµ?∑K˝)Å
  524. CrsrDevRec°dONLNdø@˝L')F    , so you °dONLNd»@'L¯)*,may use that flag to determine if the button°dONLNdıM6Y^(V6    is being °dONLNd˛M^Yo)(9clicked or released.  Your routine may destroy registers °dONLNd7LoX}(VoD0°dONLNd9M}YÖ), °dONLNd;LÖXì)D2°dONLNd=MìYõ), °dONLNd?LõX©)A0°dONLNdAM©Y¬) and °dONLNdFL¬X–)A1°dONLNdHM–Y¯)    ; it must°dONLNdRY6e∂(b6preserve all other registers.°dONLNdpr6~R*The °dONLNdtqR}…)kButtonCharStroke°dONLNdÖr…~)w and °dONLNdäq}n)'kButtonAppleScript°dONLNdúrn~¯)~ operations are currently°dONLNd∂~6äz(á6Cunimplemented and will simply cause the button press to be ignored.°dONLNd˙ñ6¢ß*CrsrDevSetButtons:°dONLNd
  525. ¢6Æç*
  526. 1Function CrsrDevSetButtons(ourDevice: CrsrDevRec;°dONLNd?Æ6∫∞* 6                           numButtons: Integer):OSErr;°dONLNdvΔ6“ª*CrsrDevSetButtons()°dONLNd⫪”ú)Ö0 allows you to set the number of buttons on the °dONLNdπ«ú”¯)·device specified by°dONLNdÕ”6flu(›6    ourDevice°dONLNd÷‘u‡Ñ)? to °dONLNd⁄”Ñfl )
  527. numButtons°dONLNd‰‘ ‡Œ)F.°dONLNdÊÔ6˚Ω(¯6CrsrDevSetAcceleration, New York°dONLNd¸ÏΩ¸¡)á:°dONLNd˛˚6∞(66Function CrsrDevSetAcceleration(ourDevice: CrsrDevRec,°dONLNd56=*  °dONLNd8~’)H1                      acceleration: Fixed):OSErr;°dONLNdj6+fi()6CrsrDevSetAcceleration()°dONLNdÇ fi,p)® lets you set the acceleration °dONLNd° p,¯)ífor the device specified by°dONLNdΩ,68u(66    ourDevice°dONLNdΔ-u9Û)? to the value specified by °dONLNd·,Û8G)~ acceleration°dONLNdÌ-G9â)T , where 0 ≤ °dONLNd˘,â8›)B acceleration°dONLNd-›9¯)T ≤ 1.°dONLNd 96Eo(B6 The Cursor °dONLNd9oE¯)9RDevice Manager will build an acceleration table for the device based on its device°dONLNdjE6Qi(N6DID or device class and the desired acceleration value.  For details °dONLNdÆEiQ¯(Nion acceleration resources, see°dONLNdÕR6^([6/"Acceleration Tables" below.  The acceleration °dONLNd¸R^P)fl
  528. table set by °dONLNd        QP]¯);CrsrDevSetAcceleration()°dONLNd    "_6kŒ(h6[is found by interpolating the tables stored in the appropriate acceleration resource.  All °dONLNd    }^Œj¯(hŒ'accl'°dONLNd    Ñk6w"(t62resources in the resource chain or in the ROM are °dONLNd    ∂k"w¯)Ï,searched looking for the one applying to the°dONLNd    „x6Ѷ(Å6specified device, so a °dONLNd    ˙x¶Ñ0)pcontrol panel which called °dONLNd
  529. w0Éÿ)äCrsrDevSetAcceleration()°dONLNd
  530. -xÿѯ)® could°dONLNd
  531. 4Ö6ëx(é6implicitly use °dONLNd
  532. CÑxê¢)B'accl'°dONLNd
  533. IÖ¢ë≥)*; resources stored within the control panel's resource fork. ¿4¿˘
  534. (’612)
  535.  of 18)µ9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇûHRˇ ˇˇˇˇRH
  536. HR,Times
  537. .+Z-Developer Technical Support(-Á January 1994 /X/
  538. °dONLNd?ZKÕ(HZCrsrDevDoubleTime, New York°dONLNd<ÕL—)s:,
  539. Courier°dONLNdKZW±(UZ1Function CrsrDevDoubleTime(ourDevice: CrsrDevRec;°dONLNdEWZcΔ* 4                           duration: LongInt):OSErr;°dONLNdzoZ{fl*CrsrDevDoubleTime()°dONLNdçpfl|)Ö6 lets you set the double-click time associated with a °dONLNd√p|(y
  540. particular°dONLNdŒ|Zà(ÖZ*device.  The duration parameter specifies °dONLNd¯|à)ƒ7the time, in ticks, to use as the double-click time for°dONLNd0àZîr(ëZ;this device.  An application could be written to check the °dONLNdkàrî(ër$double-click time for the particular°dONLNdêîZ† (ùZ&device in checking for a double-click.°dONLNd∑ØZª‘*CrsrDevUnitsPerInch°dONLNd ¨‘ºÿ)z:°dONLNdêZ«ø(≈Z3Function CrsrDevUnitsPerInch(ourDevice: CrsrDevRec;°dONLNd«Z”‘* 6                             resolution: Fixed):OSErr;°dONLNd7flZÎÌ*CrsrDevUnitsPerInch()°dONLNdL‡ÌÏ)ì °dONLNdM‡Ï)Blets you set the resolution of a particular device to its physical°dONLNdêÏZ¯L(ıZ5resolution, in units per inch.  For devices adhering °dONLNd≈ÏL¯)Ú*to the Apple extended mouse protocol, this°dONLNd¯Z„(Zcall shouldn't  be needed, as °dONLNd¯„)âAthe resolution can be read from the device's register 1; however,°dONLNdPZø(
  541. ZKthis call might be made by a driver for a device which doesn't use the ADB.°dONLNdúZ(…*Acceleration Tables°dONLNd∞5ZA∑*Acceleration tables °dONLNdƒ5∑AT)] are stored in resources of type °dONLNd‰4T@~)ù'accl'°dONLNdÍ5~A)*, which have the following Rez°dONLNd    AZMë(JZ description:
  542.     °dONLNdYZdõ*
  543. type 'accl' {°dONLNd%cln∑+
  544. literal longInt°dONLNd5c nŸ)¥%/* Device identifier or device class °dONLNd[c
  545. n)Í*/°dONLNd`m~xƒ(u~classAbsolute,°dONLNdom x¢)¢/* A flat-response device °dONLNdäm
  546. x)Í*/°dONLNdèw~ǵ(~ classMouse,°dONLNdõw Çª)¢/* Mechanical or optical mouse °dONLNdªw
  547. Ç)Í*/°dONLNd¿Å~å…(â~classTrackball;°dONLNd–Å åa)¢
  548. /* Trackball °dONLNdfiÅ
  549. å)Í*/°dONLNdÂïl†(ùlinteger = $$CountOf(AcclTable);°dONLNdï †œ)¥#/* Number of tables for this device°dONLNd)ï
  550. †)Í*/°dONLNd-ül™¡(ßlarray AcclTable {°dONLNd?ü ™˜)¥+/* Entries sorted by first value; must have°dONLNdkü
  551. ™)Í*/°dONLNdq© ¥∂(± /* at least 0.0 and 1.0 tables°dONLNdê©
  552. ¥)Í*/°dONLNdï≥~æÁ(ª~unsigned hex longint;°dONLNd´≥ æ)¢1/* Acceleration provided by this table (Fixed) */°dONLNd‚«~“(œ~integer = $$CountOf(AcclPoint);°dONLNd« “˜)¢+/* Number of control points for this device°dONLNd.«
  553. “)Í*/°dONLNd3—~‹Ï(Ÿ~wide array AcclPoint {°dONLNdJ— ‹˜)¢+/* Entries sorted by first value; implicit °dONLNdv—
  554. ‹)Í*/°dONLNd}€ Ê¸(„ ,/* first entry (0.0, 0.0); at least one more°dONLNd™€
  555. Ê)Í*/°dONLNd±Â (Ì /* entry required. °dONLNd≈Â
  556. )Í*/°dONLNdÀÔê˙˘(˜êunsigned hex longint;°dONLNd·Ô ˙¸)ê,/* Device speed (inches per second) (Fixed) °dONLNdÔ
  557. ˙)Í*/°dONLNd˘ê˘(êunsigned hex longint;°dONLNd*˘ ¸)ê,/* Cursor speed (inches per second) (Fixed) °dONLNdW˘
  558. )Í*/°dONLNd\~à( ~};°dONLNd`
  559. lv(l};°dONLNdcZ"d(Z};
  560. °dONLNdf.Z:…*The identifier for this °dONLNd~-…9Û)o'accl'°dONLNdÑ.Û:b)* resource is stored in °dONLNdõ.b:)o&the first long word; this is either an°dONLNd¬:ZFÑ(DZOSType°dONLNd»;ÑGÒ)*L four character device identifier or an integer value specifying the device °dONLNd;ÒG(DÒ    class. In°dONLNdGZS¯(PZ#either case, the device's identity °dONLNdAG¯S)û<is generally read from the device's register 1, as described°dONLNd~SZ_e(\Z6below in the section "Extended Apple Mouse Protocol." °dONLNd¥Se_(\e%The Cursor Device Manager first tries°dONLNd⁄_ZkÎ(hZto match against the specific °dONLNd¯_Îk)ë=device identifier, then against the more general class.  Each°dONLNd    6kZwÑ(uZ'accl'°dONLNd    <lÑxÚ)* resource can contain a °dONLNd    TlÚx)n@number of acceleration tables for different acceleration values;°dONLNd    ïxZÑd(ÅZ6each table contains a number of entries which match a °dONLNd    ÀxdÑ(Åd'particular device speed to a particular°dONLNd    ÛÖZëµ(éZcursor speed.  An °dONLNd
  561. ѵêfl)['accl'°dONLNd
  562. Öflë˛)*= resource must contain at least two acceleration tables, one °dONLNd
  563. HÖ˛ë(é˛for an°dONLNd
  564. OëZù5(öZ0acceleration of 0.0 and one for an acceleration °dONLNd
  565. ë5ù)€0value of 1.0.  When an acceleration value is set°dONLNd
  566. ∞ùZ©ˆ(¶ZWfor a particular device, the acceleration table is calculated by interpolating between °dONLNd ùˆ©(¶ˆthe two ¿X¿
  567. (’Z9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’ 13)
  568.  of 18(ÎZHardwareˇ‰HRˇ ˇˇˇˇRH
  569. HR,Times
  570. .+6-Macintosh Technical Notes /4/˘
  571. °dONLNd=6I£*nearest tables from the ,
  572. Courier°dONLNd<£HÕ)m'accl'°dONLNd=ÕI–)* °dONLNd=–I¯)@resource.  There is an implicit entry in each acceleration table°dONLNd`I6U (R6/of (0.0, 0.0), which indicates that the cursor °dONLNdèI U¯)’1should not move if the device does not.  At least°dONLNd¡U6aŒ(^6"one additional entry is required; °dONLNd„UŒa¯)ò>the Cursor Device Manager will use the table entries to figure°dONLNd"a6m“(j6the cursor movement by using °dONLNd?a“m¯)ú9the device movement to interpolate based on the specified°dONLNdym6yØ(v6movement control points.°dONLNdíÖ6ë,*)Availability Of The Cursor Device Manager°dONLNdºù6©c*5The Cursor Device Manager was introduced in the ROMs °dONLNdÒùc©¯(¶cof Macintoshes introduced in°dONLNd©6µú(≤6HFebruary, 1993.  It may be installed via software on any Macintosh.  To °dONLNdV©úµ¯(≤úcheck to see if the°dONLNdj∂6¬k(ø6@Cursor Device Manager is available, you should use the standard °dONLNd™µk¡Δ(øk
  573. TrapAvailable°dONLNd∑∂Δ¬¯)[  routine to°dONLNd√√6œò(Ã6Lcheck to see if its trap is implemented.  The Cursor Device Manager trap is °dONLNd¬òŒª(Ãò$AADB°dONLNd√ªœ¬)#, °dONLNd√¬œ¯) making it a°dONLNd"–6‹≤(Ÿ6toolbox trap, trap number °dONLNd<œ≤€Œ)|$2DB°dONLNd@–Œ‹“).°dONLNdBË6ÙÉ(Ò6
  574. Compatibility°dONLNdP6 —*WWhen the Cursor Device Manager is installed, all Apple mouse drivers use its interface °dONLNdß— ¯(    —to move°dONLNdØ
  575. 6·(6$the cursor; this means that the low °dONLNd”
  576. ·^)´memory globals such as °dONLNdÍ ^Å)}Mouse°dONLNdÔ
  577. Åú)# and °dONLNdÙ ú‘)RawMouse°dONLNd¸
  578. ‘¯)8 are no°dONLNd6%x("6
  579. longer used. °dONLNdx%¯)BJ While a compatibility mode keeps drivers which still modify these globals°dONLNd\%61´(.6Ocontinue to work, the cursor position can no longer be read from these globals.
  580. °dONLNd¨=6Lï*
  581. Apple Devices
  582. °dONLNd∫X6d·*Classic Apple Mouse Protocol°dONLNd◊p6|*.The original Apple mouse protocol has allowed °dONLNdp|¯)‚.for mice with a resolution of 100 or 200 units°dONLNd4|6àÄ(Ö6per inch with 7 °dONLNdD|Äà¯)JKbit accumulation of relative movement with one or two buttons. Handler ID 1°dONLNdêà6îg(ë6    was used °dONLNdôàgî¯)1Sto indicate 100 cpi operation; handler 2 to indicate 200 cpi operation. All data is°dONLNdÌî6†3(ù67transferred through register 0 in the following format:†Ç†å
  583. ¨6˙    1∏M m    ˇˇˇˇˇˇˇˇ0∑LÀn"∑^"∏q"∏É"∏ï"∏ß"∏π"∏À"∑‹"∑Ó"∏"∏"∏%"∏7"∏I"∏[°ñ °öˇ˝
  584. ≠Pπ].mƒmƒ°dONLNdˇˇ+15†ó°ñ °öˇ˝
  585. ≠bπo°dONLNdˇˇ)14†ó°ñ °öˇ˝
  586. ≠–π◊°dONLNdˇˇ)n8†ó°ñ °öˇ˝
  587. ≠‚πȰdONLNdˇˇ)7†ó°ñ °öˇ˝
  588. ≠Ùπ˚°dONLNdˇˇ)6†ó°ñ °öˇ˝
  589. ≠`πg°dONLNdˇˇ)l0†ó°ñ °öˇ˝    
  590. ≠7πK°dONLNdˇˇ(∂8Bit:†ó
  591. ¨6˙"”d    "”R    "”@    "”.    "”    "”
  592.     "”¯    !‹"”Ê!Ó"”‘- h V#¡"”¬-"”∞-"”û-"”å-"”z-"”h-°ñ °öˇ¸#
  593.  à—°dONLNdˇˇ(âButton pressed†ó°ñ °öˇ¸$
  594. ˙à‘&¿°dONLNdˇˇ(âY motion value†ó°ñ °öˇ¸7
  595. ËàÙ˘ÕİdONLNdˇˇ(ÒâOptional second button†ó°ñ °öˇ¸$
  596. ÷à‚‘»°dONLNdˇˇ(flâX motion value†ó†ç†É
  597. HR.°dONLNd%%ù1ê(.ù(Figure 1–Classic Mouse Register 0 Format°dONLNdN=6I#(F62Where relative motion in each axis is accumulated °dONLNdÄ=#I¯)Ì,until fetched with a talk register 0 command°dONLNd≠I6Ut(R6Csent by the host. The X value represents left-to-right motion, the °dONLNdItU¯(RtY value holds accumulated°dONLNd
  598. U6a´(^6forward-to-back motion.°dONLNd"m6yÏ*Extended Apple Mouse Protocol°dONLNd@Ö6ë±*In order to be able to take °dONLNd\Ö±ë¯){Badvantage of the higher movement resolution support available with°dONLNdüë6ùÆ(ö6Mthe Cursor Device Manager, an extended mouse protocol has been defined; this °dONLNdÏëÆù¯(öÆallows a device°dONLNd¸ù6©H(¶68to communicate up to 16 bits of movement data with each °dONLNd4ùH©¯(¶H$polling and allows a standard device°dONLNdY©6µ›(≤6$to communicate the state of up to 8 °dONLNd}©›µ¯)ß:buttons. In addition, the new format allows each device to ¿4¿˘
  599. (’614)
  600.  of 18)µ9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇåHRˇ ˇˇˇˇRH
  601. HR,Times
  602. .+Z-Developer Technical Support(-Á January 1994 /X/
  603. °dONLNd<ZHƒ(EZMcommunicate its exact type, resolution and class. This new format applies to °dONLNdM<ƒH(Eƒall relative devices°dONLNdbHZT˚(QZ#at default address 3, handler ID 4.°dONLNdÜ`Zl»*JDuring startup or after a reset of the ADB bus, devices which power up at °dONLNd–`»l(i»default address 3°dONLNd‚lZx≈(uZLwith handler ID 1 will be switched to handler ID 4 with a listen register 3 °dONLNd.l≈x(u≈command.  If the°dONLNd?xZщ(ÅZTdevice accepts the switch and reports the new handler ID of 4 back in response to a °dONLNdìx‰Ñ(ʼn
  604. talk register°dONLNd°ÑZêö(çZ=3 command, all subsequent communication with the device will °dONLNdfiÑöê(çöbe assumed to follow the°dONLNd˜êZú%(ôZ)extended mouse protocol.  Currently, the °dONLNd ê%ú)À-ADB manager makes an additional check, making°dONLNdNúZ®"(•Z,sure that a talk register 1 returns 8 bytes °dONLNdzú"®)»4(the format of register 1 is specified below).  If a°dONLNdØ®Z¥¬(±ZMdevice accepts a handler ID change but does not return 8 bytes from register °dONLNd¸®¬¥(±¬1, it is assumed to°dONLNd¥Z¿‹(ΩZnot actually be an extended °dONLNd,¥‹¿)ÇBmouse protocol device and is switched back to its original handler°dONLNdo¿ZÃj(…ZID.°dONLNdsÿZ‰k*All °dONLNdwÿk‰)Vmovement and button data still passes through register 0, which can now hold between 2°dONLNdŒ‰Z‹(ÌZand 5 bytes, where 2 bytes °dONLNdȉ‹)ÇEprovides the device with the data transfer capability of the original°dONLNd/Z¸∞(˘ZGmouse protocol and additional bytes allow added resolution and buttons.°dONLNdwZL*1Bytes 0 and 1 of register 0 have the same format °dONLNd®L)Ú*as they did in the classic mouse protocol,°dONLNd”Z ü(ZCcommunicating the state of the first two buttons and the low order °dONLNdü (ü7 bits of the accumulated°dONLNd0 Z,?()Z0motion in the X and Y axes.  There can be up to °dONLNd` ?,)Â.3 bytes of additional information: each one of°dONLNdè,Z8(5Z these bytes can communicate the °dONLNdØ,8)¶6state of 2 more buttons and add 3 higher order bits of°dONLNdÊ8ZDƒ(AZNresolution to each of the X and Y axes. The format of each additional byte is:†Ç†å
  605. PòΩ›    1\Øn?    ˇˇˇˇˇˇˇˇ0[Æo@"[¿"\”"\Â"[ˆ"["\"\-°ñ °öˇ˝    
  606. Qô]≠.mEmE°dONLNdˇˇ+@Bit:†ó°ñ °öˇ˝
  607. Q¥]ªÅİdONLNdˇˇ)7†ó°ñ °öˇ˝
  608. QΔ]ÕÅİdONLNdˇˇ)6†ó°ñ °öˇ˝
  609. Q2]9ÅİdONLNdˇˇ)l0†ó°ñ °öˇ˝
  610. Q¸]ÅİdONLNdˇˇ(Z˝3†ó°ñ °öˇ˝
  611. Q]ÅİdONLNdˇˇ)2†ó°ñ °öˇ˝
  612. QÍ]ÒÅİdONLNdˇˇ(ZÎ4†ó
  613. PòΩ›"Ä?"w6    "w$    "w    "w#Q"wÓ- § §Q"w∏?!∂Q"w‹-"w -°ñ °öˇ¸4
  614. ∞ZºΔ°dONLNdˇˇ+p_First additional button†ó°ñ °öˇ¸?
  615. ûZ™‹'¿°dONLNdˇˇ(ß[Additional Y motion value†ó°ñ °öˇ¸;
  616. åZò”!¿°dONLNdˇˇ(ï[Second additional button†ó°ñ °öˇ¸?
  617. zZÜ‹İdONLNdˇˇ(É[Additional X motion value†ó†ç†É
  618. HR.°dONLNd5…[’(“[JFigure 2–Format Of Additional Register 0 Bytes For Extended Mouse Protocol°dONLNdÄ·ZÌ€(ÍZAs a specific example, in a °dONLNdú·€Ì)ÅBmaximal 5 byte transmission, the data would be transferred in this°dONLNdflÌZ˘|(ˆZformat:°dONLNdÁ«·+mBit #:°dONLNdÓˆ))7°dONLNd )6°dONLNdÚ)/)5°dONLNdÙFL)4°dONLNdˆci)3°dONLNd¯ÄÜ)2°dONLNd˙ú¢)1°dONLNd¸πø)0"‰ °dONLNdˇø·(øByte 0:°dONLNdÌ˘).b0°dONLNd
  619. )y06°dONLNd#5)y05°dONLNd@R)y04°dONLNd]o)y03°dONLNdzå)y02°dONLNdñ®)y01°dONLNd"≥≈)y00"≥0"‰"Â""""":";"W"X"t"u"ê"ë"≠"Æ"‰ °dONLNd'ø*·('øByte 1:°dONLNd/Ì*˘).b1°dONLNd2*)x06°dONLNd6#*5)x05°dONLNd:@*R)x04°dONLNd>]*o)x03°dONLNdBz*å)x02°dONLNdFñ*®)x01°dONLNdJ≥*≈)x00"‰ °dONLNdO*ø6·(3øByte 2:°dONLNdW*Ì6˘).b2°dONLNdZ*6)y09°dONLNd^*#65)y08°dONLNdb*@6R)y07°dONLNdf*`6l) b3°dONLNdi*z6å)x09°dONLNdm*ñ6®)x08°dONLNdq*≥6≈)x07"*‰ °dONLNdv6øB·(?øByte 3:°dONLNd~6ÌB˘).b4°dONLNdÅ6B)y12°dONLNdÖ6#B5)y11°dONLNdâ6@BR)y10°dONLNdç6`Bl) b5°dONLNdê6zBå)x12°dONLNdî6ñB®)x11°dONLNdò6≥B≈)x10"6‰ °dONLNdùBøN·(KøByte 4:°dONLNd•BÌN˘).b6°dONLNd®BN)y15°dONLNd¨B#N5)y14°dONLNd∞B@NR)y13°dONLNd¥B`Nl) b7°dONLNd∑BzNå)x15°dONLNdªBñN®)x14°dONLNdøB≥N≈)x13"B‰ °dONLNd≈Z£f”(c£3Table 2–Format Of A 5 Byte Register 0 Data Transfer°dONLNd˘rZ~Ç({ZWhere b°dONLNdrÇ~à)(n°dONLNdrà~Û) indicates the status of °dONLNdrÛ~)kbutton °dONLNd!r~)"n°dONLNd"r~:) and x°dONLNd(r:~D)aa°dONLNd*rD~\)
  620.  or y°dONLNd/r\~h)bb°dONLNd1rh~Ê)  indicates the value of bit °dONLNdMrÊ~)~aa°dONLNdOr~)
  621.  or °dONLNdSr~)bb°dONLNdUr~)  of°dONLNdY~Zäƒ(áZthe X or Y movement. ¿X¿
  622. *N9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’ 15)
  623.  of 18(ÎZHardwareˇ‡HRˇ ˇˇˇˇRH
  624. HR,Times
  625. .+6-Macintosh Technical Notes /4/˘
  626. °dONLNd<6HM*6In addition, register 1 is used in the extended mouse °dONLNd6<MH¯(EM protocol to provide some general°dONLNdWH6T«(Q6Winformation about the device.  Register 1 is 8 bytes long and is formatted in this way:°dONLNdØ`Ülπ+P
  627. Byte range°dONLNd∫`%lG)üFormat"lyK"`≈ "l≈ lΔl•°dONLNd¬mòy®(vò0-3°dONLNdΔm y;)2Unique device identifier"lyK"l≈ lΔl•"m≈ °dONLNd‡yòÖ®(Çò4-5°dONLNd‰y ÖY)2Device resolution in units/inch"y≈ °dONLNdÖùë£(éù6°dONLNdÖ ëÇ)-&Device class (Mouse, trackball, etc.…)"Ö≈ °dONLNd/ëùù£(öù7°dONLNd1ë ù?)-Number of buttons (0-8)"ë≈ °dONLNdK©xµ∂(≤x4Table 3–Format Of Extended Mouse Protocol Register 1°dONLNdÄ¡6Õ5( 66The unique device identifier is intended to be a four °dONLNd∂¡5Õ¯)ˇ)character ASCII identifier similar to the,
  628. Courier°dONLNd‡Õ6Ÿ`(◊6OSType°dONLNdÊŒ`⁄√)* identifiers used as °dONLNd˚Œ√⁄¯)c<types and creators in the Macintosh file system; they can be°dONLNd8⁄6Êæ(„6Pregistered using the same mechanism used to register creator types. A developer °dONLNdà⁄æÊ¯(„æ should only°dONLNdîÊ6Ú|(Ô6Kuse a device identifier in this field if they have obtained a registration °dONLNdflÊ|Ú¯(Ô|for that identifier's use as°dONLNd¸Ú6˛õ(˚6a creator from Apple.°dONLNd
  629. 6Í*XThe device class is a value which is used to identify the type of device and to control °dONLNdj
  630. ͯ(Íthe°dONLNdn6"Ø(6Racceleration curve used for that device.  The currently defined constants include:°dONLNd¡.z:ƒ+DDevice constant°dONLNd—.:V)• Device type".… °dONLNdfi;úG¢(Dú0°dONLNd‡;ŒG{)2%Tablet device (absolutely positioned)":tT":… : :©";… °dONLNdGúS¢(Pú1°dONLNd    GŒSÓ)2Mouse"G… °dONLNdSú_¢(\ú2°dONLNdSŒ_˙)2    Trackball"S… °dONLNdk¢wã(t¢(Table 4–Currently defined device classes°dONLNdGÉ6è±(å6There currently isn't any °dONLNdaɱè¯){Cmechanism for developers to create or register device classes; if a°dONLNd•è6õT(ò6=developer needs a device class not available from Apple, the °dONLNd‚èTõ¯(òT$only alternative available currently°dONLNdõ6ß>(§68is not to use the handler ID 4 extended mouse protocol, °dONLNd?õ>߯(§>%instead using a custom handler ID and°dONLNdeß6≥ß(∞6custom driver software.°dONLNd}ø6À≈*Apple Keyboard protocol°dONLNdï◊6„Ñ*DThe Apple keyboards have a simple data transfer protocol.  Register °dONLNdŸ◊Ñ„¯(‡Ñ0 is used to inform the°dONLNdÒ„6Ô\(Ï6host as °dONLNd˘„\Ô¯)&Skeys are depressed and released; register 2 is used to communicate the state of the°dONLNdMÔ6˚õ(¯6Jmodifier keys and to control the LED indicators on the extended keyboards.°dONLNdò6¥*The format of register 0 is:†Ç
  631. EåÈ    1+\=|    ˇˇˇˇˇˇˇˇ0*[>}"*m"+Ä"+í"+§"+∂"+»"+⁄"*Î"*˝"+"+""+4"+F"+X"+j°ñ °öˇ˝
  632.  _,l.m§m§°dONLNdˇˇ+*15†ó°ñ °öˇ˝
  633.  q,~°dONLNdˇˇ)14†ó°ñ °öˇ˝
  634.  fl,ʰdONLNdˇˇ)n8†ó°ñ °öˇ˝
  635.  Ò,¯°dONLNdˇˇ)7†ó°ñ °öˇ˝
  636.  ,
  637. °dONLNdˇˇ)6†ó°ñ °öˇ˝
  638.  o,v°dONLNdˇˇ)l0†ó°ñ °öˇ˝    
  639.  F,Z°dONLNdˇˇ()GBit:†ó
  640. EåÈ"Fs    "Fa    "FO    "F=    "F+    "F    "F    !Oé"Fı!aé"F„- swsé ÖéÖe#¡"F—-"Fø-"F≠-"Fõ-"Fâ-"Fw-°ñ °öˇ¸#
  641. óㇰdONLNdˇˇ(àòKey 1 released†ó°ñ °öˇ¸'
  642. móyË…¿°dONLNdˇˇ(vòKey code field 1†ó°ñ °öˇ¸#
  643. [óg‡j¿°dONLNdˇˇ(dòKey 2 released†ó°ñ °öˇ¸'
  644. IóU˥İdONLNdˇˇ(RòKey code field 2†ó†É
  645. HR.°dONLNdµò´§É(°´#Figure 3–Keyboard Register 0 Format ¿4¿˘
  646. (’616)
  647.  of 18)µ9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇ HRˇ ˇˇˇˇRH
  648. HR,Times
  649. .+Z-Developer Technical Support(-Á January 1994 /X/
  650. °dONLNd<ZH (EZ]Register 0 can communicate up to two key transitions at once.  Each transition consists of a °dONLNd]< H(E key°dONLNdaHZTs(QZcode °dONLNdfHsT)Wand a key released bit, which is 0 for key depressions and 1 for key releases.  The key°dONLNdæTZ`…(]Zcodes are described in °dONLNd’T…`)oInside Macintosh°dONLNdÂT`V)R  volume V, °dONLNdTV`);'pages 191-192.  The special case is the°dONLNd`Zlœ(iZreset key, which returns °dONLNd1`œl)uAthe value $7F7F in register 0 when it is depressed and $FFFF when°dONLNdslZxÜ(uZBreleased; thus, it uses both key code positions within register 0.°dONLNd∂ÑZêÿ*The format of register 2 is:†Ç†å
  651. úfæ    1®}∫ù    ˇˇˇˇˇˇˇˇ0ß|ªû"ßé"߆"ß≤"߃"ß÷"ßË"ß˙"ß "ß"ß0"®C"®U"ßf"ßx"ßä°ñ °öˇ˝    
  652. ùg©{."©"©°dONLNdˇˇ+Bit:†ó°ñ °öˇ˝
  653. ùÄ©çÅİdONLNdˇˇ)15†ó°ñ °öˇ˝
  654. ùí©üÅİdONLNdˇˇ)14†ó°ñ °öˇ˝
  655. ù©ÅİdONLNdˇˇ)o8†ó°ñ °öˇ˝
  656. ù©ÅİdONLNdˇˇ)7†ó°ñ °öˇ˝
  657. ù$©+ÅİdONLNdˇˇ)6†ó°ñ °öˇ˝
  658. ùê©óÅİdONLNdˇˇ)l0†ó°ñ °öˇ˝
  659. ù§©±ÅİdONLNdˇˇ(¶•13†ó°ñ °öˇ˝
  660. ù∂©√ÅİdONLNdˇˇ)12†ó°ñ °öˇ˝
  661. ù»©’ÅİdONLNdˇˇ)11†ó°ñ °öˇ˝
  662. ù⁄©ÁÅİdONLNdˇˇ)10†ó°ñ °öˇ˝
  663. ùÔ©ˆÅİdONLNdˇˇ)9†ó°ñ °öˇ˝
  664. ù6©=ÅİdONLNdˇˇ)G5†ó°ñ °öˇ˝
  665. ùZ©aÅİdONLNdˇˇ)$3†ó°ñ °öˇ˝
  666. ùl©sÅİdONLNdˇˇ)2†ó°ñ °öˇ˝
  667. ù~©ÖÅİdONLNdˇˇ)1†ó
  668. úfæ"Ãî"fiÇ$"p6"¶î"¶Ç &¶& 8¶8 J¶JÚ \¶\‡ n¶nŒ Ä¶ĺ í™í¶ §¶§ò ∂¶∂Ü √Ü∂Ü §ò√ò √™í™ ĺ√º √ŒnŒ \‡√‡ √ÚJÚ"8ã"√c"(Ø"√:?"√L?"√^?"p”"fiÇÂ"√î    °ñ °öˇ˝,
  669. «Ø”    °dONLNdˇˇ+1*LED 1 (num lock)†ó°ñ °öˇ˝,
  670. ŸØÂ    Õ¿°dONLNdˇˇ*LED 2 (caps lock)†ó°ñ °öˇ˝.
  671. Îؘ¿°dONLNdˇˇ*LED 3 (scroll lock)†ó°ñ °öˇ˝
  672. ˝Ø    ›∑İdONLNdˇˇ*Reserved†ó°ñ °öˇ˝
  673. ØÂ\°dONLNdˇˇ* Scroll lock†ó°ñ °öˇ˝(
  674. !Ø-≠İdONLNdˇˇ*Num lock / clear†ó°ñ °öˇ˝*
  675. 3Ø?˘Ä°dONLNdˇˇ*Apple / command†ó°ñ °öˇ˝
  676. EØQ“Û¿°dONLNdˇˇ*Option†ó°ñ °öˇ˝ 
  677. WØc»HİdONLNdˇˇ*Shift†ó°ñ °öˇ˝
  678. iØu’ùİdONLNdˇˇ*Control†ó°ñ °öˇ˝
  679. 
  680. {ØáÀG¿°dONLNdˇˇ*Reset†ó°ñ °öˇ˝
  681. çØô‡°dONLNdˇˇ*    Caps lock†ó°ñ °öˇ˝
  682. üØ´–ò@°dONLNdˇˇ*Delete†ó°ñ °öˇ˝
  683. ±ØΩ›ÁİdONLNdˇˇ*Reserved†ó†ç†É
  684. HR.°dONLNd” œ÷ß(”œ#Figure 4–Keyboard Register 2 Format°dONLNd˜‚ZÓ±(ÎZKThe current state of the keys listed in figure 4 is available in bits 6-14 °dONLNdB‚±Ó(αof register 2, if those°dONLNdZÓZ˙Å(˜Z>keys exist on the keyboard being examined.  Bits 0-2 hold the °dONLNdòÓÅ˙(˜Å current state of the LEDs on the°dONLNdπ˙Z (Zextended keyboard; the °dONLNd–˙ )pDstates of these LEDs can be changed by sending the keyboard a listen°dONLNdZn(Z9register 2 command.  Note that key transition events are °dONLNdNn(n$generated in register 0 for modifier°dONLNdsZ(Z?keys, as they are for all other keys; these keys are available °dONLNd≤("in register 2 in addition to their°dONLNd’Z*$('Z,status being transmitted through register 0. ¿X¿
  685. *Æ9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse(’ 17)
  686.  of 18(ÎZHardwareˇ¬HRˇ ˇˇˇˇRH
  687. HR,Times
  688. .+6-Macintosh Technical Notes /4/˘
  689. °dONLNd<6K}*
  690. Miscellany
  691. °dONLNd W6cm*    Licensing°dONLNdo6{™*The Apple Desktop Bus °dONLNd,o™{¯)tEis patented.  In order to build an ADB device, you will need to get a°dONLNdr{6á¿(Ñ6license from Apple.  Contact:°dONLNdêìZü’+$Apple Software Licensing°dONLNd©üZ´¬* Apple Computer, Inc.°dONLNdæ´Z∑¯* 20525 Mariani Avenue, M/S 38-I°dONLNd›∑Z√”* Cupertino, CA       95014°dONLNd˜√Zœ•* (408) 974-4667°dONLNd€ZÁŸ*AppleLink: SW.LICENSE°dONLNdÁZÛ6* (Internet: SW.LICENSE@applelink.apple.com°dONLNdEˇ6 (6.The license is available for a nominal fee in °dONLNdsˇ ¯)Œ2most cases, and the licensing package includes the°dONLNd¶ 6õ(6Nlatest version of the ADB spec., which is the definitive reference to the bus.°dONLNdı#6/†*Further Reference: /4/˘°dONLNd0H<L+
  692. •°dONLNd
  693. 0Z<D)0The Apple Desktop Bus specification, revision F.°dONLNd;<HHL(EH•°dONLNd=<ZH´)Inside Macintosh°dONLNdM<´Hú)Q/, Volume V, chapter 20, "The Apple Desktop Bus"°dONLNd}HHTL(QH•°dONLNdHZT)&Guide to the Macintosh Family Hardware°dONLNd•HTK)ƒ    , Second °dONLNdÆHKT¯)-"Edition, Chapter 8, "Apple Desktop°dONLNd—TZ`r(]ZBus" ¿4¿˘
  694. (’618)
  695.  of 18)µ9HW 1 – ADB - The Untold Story : Space Aliens Ate My Mouse+flHardwareˇ